Skip to content

Commit 0f332e1

Browse files
authored
Merge pull request #73831 from atrick/remove-bitwise-lifetime-diagnostic
Remove diagnostic: lifetime_dependence_on_bitwise_copyable
2 parents 64da348 + b5b0c75 commit 0f332e1

29 files changed

+98
-100
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7985,8 +7985,6 @@ ERROR(lifetime_dependence_cannot_infer_ambiguous_candidate, none,
79857985
"expected nil or self as return values in an initializer with "
79867986
"lifetime dependent specifiers",
79877987
())
7988-
ERROR(lifetime_dependence_on_bitwise_copyable, none,
7989-
"invalid lifetime dependence on BitwiseCopyable type", ())
79907988
ERROR(lifetime_dependence_cannot_be_applied_to_tuple_elt, none,
79917989
"lifetime dependence specifiers cannot be applied to tuple elements", ())
79927990
ERROR(lifetime_dependence_method_escapable_bitwisecopyable_self, none,

lib/AST/LifetimeDependence.cpp

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -207,24 +207,16 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd) {
207207
Type paramType,
208208
ValueOwnership ownership) {
209209
auto loc = specifier.getLoc();
210-
211-
// Diagnose when we have lifetime dependence on a type that is
212-
// BitwiseCopyable & Escapable.
213-
// ~Escapable types are non-trivial in SIL and we should not raise this
214-
// error.
215-
// TODO: Diagnose ~Escapable types are always non-trivial in SIL.
216-
if (paramType->isEscapable()) {
217-
if (isBitwiseCopyable(paramType, mod, ctx)) {
218-
diags.diagnose(loc, diag::lifetime_dependence_on_bitwise_copyable);
219-
return true;
220-
}
221-
}
222-
223210
auto parsedLifetimeKind = specifier.getParsedLifetimeDependenceKind();
224211
auto lifetimeKind =
225212
getLifetimeDependenceKindFromDecl(parsedLifetimeKind, paramType);
226-
bool isCompatible = isLifetimeDependenceCompatibleWithOwnership(
213+
bool isCompatible = true;
214+
// Lifetime dependence always propagates through temporary BitwiseCopyable
215+
// values, even if the dependence is scoped.
216+
if (!isBitwiseCopyable(paramType, mod, ctx)) {
217+
isCompatible = isLifetimeDependenceCompatibleWithOwnership(
227218
lifetimeKind, ownership, afd);
219+
}
228220
if (parsedLifetimeKind == ParsedLifetimeDependenceKind::Scope &&
229221
!isCompatible) {
230222
diags.diagnose(

test/ModuleInterface/Inputs/lifetime_dependence.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
public struct AnotherView : ~Escapable {
22
@usableFromInline let _ptr: UnsafeRawBufferPointer
33
@usableFromInline let _count: Int
4-
@_unsafeNonescapableResult
5-
internal init(_ ptr: UnsafeRawBufferPointer, _ count: Int) {
4+
internal init(_ ptr: UnsafeRawBufferPointer, _ count: Int) -> dependsOn(ptr) Self {
65
self._ptr = ptr
76
self._count = count
87
}
@@ -11,9 +10,8 @@ public struct AnotherView : ~Escapable {
1110
public struct BufferView : ~Escapable {
1211
@usableFromInline let _ptr: UnsafeRawBufferPointer
1312
@usableFromInline let _count: Int
14-
@_unsafeNonescapableResult
1513
@usableFromInline
16-
internal init(_ ptr: UnsafeRawBufferPointer, _ count: Int) {
14+
internal init(_ ptr: UnsafeRawBufferPointer, _ count: Int) -> dependsOn(ptr) Self {
1715
self._ptr = ptr
1816
self._count = count
1917
}

test/Parse/explicit_lifetime_dependence_specifiers.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import Builtin
55

66
struct BufferView : ~Escapable {
77
let ptr: UnsafeRawBufferPointer
8-
@_unsafeNonescapableResult
9-
init(_ ptr: UnsafeRawBufferPointer) {
8+
init(_ ptr: UnsafeRawBufferPointer) -> dependsOn(ptr) Self {
109
self.ptr = ptr
1110
}
11+
// TODO: -> dependsOn(ptr) Self
1212
@_unsafeNonescapableResult
1313
init?(_ ptr: UnsafeRawBufferPointer, _ i: Int) {
1414
if (i % 2 == 0) {
@@ -45,8 +45,7 @@ struct BufferView : ~Escapable {
4545

4646
struct MutableBufferView : ~Escapable, ~Copyable {
4747
let ptr: UnsafeMutableRawBufferPointer
48-
@_unsafeNonescapableResult
49-
init(_ ptr: UnsafeMutableRawBufferPointer) {
48+
init(_ ptr: UnsafeMutableRawBufferPointer) -> dependsOn(ptr) Self {
5049
self.ptr = ptr
5150
}
5251
}

test/SIL/Parser/lifetime_dependence.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import Swift
88

99
struct BufferView : ~Escapable {
1010
@_hasStorage let ptr: UnsafeRawBufferPointer { get }
11-
@_unsafeNonescapableResult @inlinable init(_ ptr: UnsafeRawBufferPointer)
11+
@inlinable init(_ ptr: UnsafeRawBufferPointer) -> _scope(ptr) Self
1212
init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array<Int>) -> _scope(a) Self
1313
}
1414

test/SIL/explicit_lifetime_dependence_specifiers.swift

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,21 @@ import Builtin
88

99
struct BufferView : ~Escapable {
1010
let ptr: UnsafeRawBufferPointer
11-
@_unsafeNonescapableResult
12-
init(_ ptr: UnsafeRawBufferPointer) {
11+
init(_ ptr: UnsafeRawBufferPointer) -> dependsOn(ptr) Self {
1312
self.ptr = ptr
1413
}
14+
// TODO: -> dependsOn(ptr) Self
1515
@_unsafeNonescapableResult
1616
init?(_ ptr: UnsafeRawBufferPointer, _ i: Int) {
1717
if (i % 2 == 0) {
1818
return nil
1919
}
2020
self.ptr = ptr
2121
}
22+
@_unsafeNonescapableResult
23+
init(independent ptr: UnsafeRawBufferPointer) {
24+
self.ptr = ptr
25+
}
2226
// CHECK: sil hidden @$s39explicit_lifetime_dependence_specifiers10BufferViewVyACSW_SaySiGhYlstcfC : $@convention(method) (UnsafeRawBufferPointer, @guaranteed Array<Int>, @thin BufferView.Type) -> _scope(1) @owned BufferView {
2327
init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array<Int>) -> dependsOn(a) Self {
2428
self.ptr = ptr
@@ -38,8 +42,7 @@ struct BufferView : ~Escapable {
3842

3943
struct MutableBufferView : ~Escapable, ~Copyable {
4044
let ptr: UnsafeMutableRawBufferPointer
41-
@_unsafeNonescapableResult
42-
init(_ ptr: UnsafeMutableRawBufferPointer) {
45+
init(_ ptr: UnsafeMutableRawBufferPointer) -> dependsOn(ptr) Self {
4346
self.ptr = ptr
4447
}
4548
}
@@ -57,28 +60,28 @@ func testBasic() {
5760

5861
// CHECK: sil hidden @$s39explicit_lifetime_dependence_specifiers6deriveyAA10BufferViewVADYlsF : $@convention(thin) (@guaranteed BufferView) -> _scope(0) @owned BufferView {
5962
func derive(_ x: borrowing BufferView) -> dependsOn(scoped x) BufferView {
60-
return BufferView(x.ptr)
63+
return BufferView(independent: x.ptr)
6164
}
6265

6366
// CHECK: sil hidden @$s39explicit_lifetime_dependence_specifiers16consumeAndCreateyAA10BufferViewVADnYliF : $@convention(thin) (@owned BufferView) -> _inherit(0) @owned BufferView {
6467
func consumeAndCreate(_ x: consuming BufferView) -> dependsOn(x) BufferView {
65-
return BufferView(x.ptr)
68+
return BufferView(independent: x.ptr)
6669
}
6770

6871
// CHECK: sil hidden @$s39explicit_lifetime_dependence_specifiers17deriveThisOrThat1yAA10BufferViewVADYls_ADYlstF : $@convention(thin) (@guaranteed BufferView, @guaranteed BufferView) -> _scope(0, 1) @owned BufferView {
6972
func deriveThisOrThat1(_ this: borrowing BufferView, _ that: borrowing BufferView) -> dependsOn(scoped this, that) BufferView {
7073
if (Int.random(in: 1..<100) == 0) {
71-
return BufferView(this.ptr)
74+
return BufferView(independent: this.ptr)
7275
}
73-
return BufferView(that.ptr)
76+
return BufferView(independent: that.ptr)
7477
}
7578

7679
// CHECK: sil hidden @$s39explicit_lifetime_dependence_specifiers17deriveThisOrThat2yAA10BufferViewVADYls_ADnYlitF : $@convention(thin) (@guaranteed BufferView, @owned BufferView) -> _inherit(1) _scope(0) @owned BufferView {
7780
func deriveThisOrThat2(_ this: borrowing BufferView, _ that: consuming BufferView) -> dependsOn(scoped this) dependsOn(that) BufferView {
7881
if (Int.random(in: 1..<100) == 0) {
79-
return BufferView(this.ptr)
82+
return BufferView(independent: this.ptr)
8083
}
81-
return BufferView(that.ptr)
84+
return BufferView(independent: that.ptr)
8285
}
8386

8487
func use(_ x: borrowing BufferView) {}
@@ -101,19 +104,18 @@ struct Wrapper : ~Escapable {
101104

102105
struct Container : ~Escapable {
103106
let ptr: UnsafeRawBufferPointer
104-
@_unsafeNonescapableResult
105-
init(_ ptr: UnsafeRawBufferPointer) {
107+
init(_ ptr: UnsafeRawBufferPointer) -> dependsOn(ptr) Self {
106108
self.ptr = ptr
107109
}
108110
}
109111

110112
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers16getConsumingViewyAA06BufferG0VAA9ContainerVnYliF : $@convention(thin) (@owned Container) -> _inherit(0) @owned BufferView {
111113
func getConsumingView(_ x: consuming Container) -> dependsOn(x) BufferView {
112-
return BufferView(x.ptr)
114+
return BufferView(independent: x.ptr)
113115
}
114116

115117
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers16getBorrowingViewyAA06BufferG0VAA9ContainerVYlsF : $@convention(thin) (@guaranteed Container) -> _scope(0) @owned BufferView {
116118
func getBorrowingView(_ x: borrowing Container) -> dependsOn(scoped x) BufferView {
117-
return BufferView(x.ptr)
119+
return BufferView(independent: x.ptr)
118120
}
119121

test/SIL/implicit_lifetime_dependence.swift

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@
66
struct BufferView : ~Escapable {
77
let ptr: UnsafeRawBufferPointer
88
let c: Int
9+
init(_ ptr: UnsafeRawBufferPointer, _ c: Int) -> dependsOn(ptr) Self {
10+
self.ptr = ptr
11+
self.c = c
12+
}
913
@_unsafeNonescapableResult
10-
init(_ ptr: UnsafeRawBufferPointer, _ c: Int) {
14+
init(independent ptr: UnsafeRawBufferPointer, _ c: Int) {
1115
self.ptr = ptr
1216
self.c = c
1317
}
@@ -31,8 +35,7 @@ struct BufferView : ~Escapable {
3135
struct MutableBufferView : ~Escapable, ~Copyable {
3236
let ptr: UnsafeMutableRawBufferPointer
3337
let c: Int
34-
@_unsafeNonescapableResult
35-
init(_ ptr: UnsafeMutableRawBufferPointer, _ c: Int) {
38+
init(_ ptr: UnsafeMutableRawBufferPointer, _ c: Int) -> dependsOn(ptr) Self {
3639
self.ptr = ptr
3740
self.c = c
3841
}
@@ -54,12 +57,12 @@ func derive(_ x: borrowing BufferView) -> BufferView {
5457
}
5558

5659
func derive(_ unused: Int, _ x: borrowing BufferView) -> BufferView {
57-
return BufferView(x.ptr, x.c)
60+
return BufferView(independent: x.ptr, x.c)
5861
}
5962

6063
// CHECK: sil hidden @$s28implicit_lifetime_dependence16consumeAndCreateyAA10BufferViewVADnYliF : $@convention(thin) (@owned BufferView) -> _inherit(0) @owned BufferView {
6164
func consumeAndCreate(_ x: consuming BufferView) -> BufferView {
62-
return BufferView(x.ptr, x.c)
65+
return BufferView(independent: x.ptr, x.c)
6366
}
6467

6568
func use(_ x: borrowing BufferView) {}
@@ -135,8 +138,7 @@ struct GenericBufferView<Element> : ~Escapable {
135138
count: count)
136139
}
137140
// unsafe private API
138-
@_unsafeNonescapableResult
139-
init(baseAddress: Pointer, count: Int) {
141+
init(baseAddress: Pointer, count: Int) -> dependsOn(baseAddress) Self {
140142
precondition(count >= 0, "Count must not be negative")
141143
self.baseAddress = baseAddress
142144
self.count = count

test/SIL/lifetime_dependence_generics.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ extension P {
1515
}
1616

1717
public struct View: ~Escapable {
18+
// TODO: dependsOn(immortal)
1819
@_unsafeNonescapableResult
1920
init() { }
2021
}

test/SIL/type_lowering_unit.sil

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ extension GSNCInt: Copyable where T: Copyable {}
248248

249249
struct GSNEInt<T: ~Escapable>: ~Escapable {
250250
var x: Int
251+
// TODO: dependsOn(immortal)
251252
@_unsafeNonescapableResult
252253
init() { x = 0 }
253254
}

test/SILOptimizer/lifetime_dependence_borrow.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ struct BV : ~Escapable {
2121

2222
public var isEmpty: Bool { i == 0 }
2323

24-
@_unsafeNonescapableResult
25-
init(_ p: UnsafeRawPointer, _ i: Int) {
24+
init(_ p: UnsafeRawPointer, _ i: Int) -> dependsOn(p) Self {
2625
self.p = p
2726
self.i = i
2827
}
@@ -38,8 +37,7 @@ struct MBV : ~Escapable, ~Copyable {
3837
let p: UnsafeRawPointer
3938
let i: Int
4039

41-
@_unsafeNonescapableResult
42-
init(_ p: UnsafeRawPointer, _ i: Int) {
40+
init(_ p: UnsafeRawPointer, _ i: Int) -> dependsOn(p) Self {
4341
self.p = p
4442
self.i = i
4543
}

test/SILOptimizer/lifetime_dependence_borrow_fail.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ struct BV : ~Escapable {
1313
let i: Int
1414

1515
@_unsafeNonescapableResult
16-
init(_ p: UnsafeRawPointer, _ i: Int) {
16+
init(_ p: UnsafeRawPointer, _ i: Int) -> dependsOn(p) Self {
1717
self.p = p
1818
self.i = i
1919
}
@@ -23,7 +23,6 @@ struct NC : ~Copyable {
2323
let p: UnsafeRawPointer
2424
let i: Int
2525

26-
@_unsafeNonescapableResult
2726
init(_ p: UnsafeRawPointer, _ i: Int) {
2827
self.p = p
2928
self.i = i
@@ -38,7 +37,7 @@ struct NE : ~Escapable {
3837
let i: Int
3938

4039
@_unsafeNonescapableResult
41-
init(_ p: UnsafeRawPointer, _ i: Int) {
40+
init(_ p: UnsafeRawPointer, _ i: Int) -> dependsOn(p) Self {
4241
self.p = p
4342
self.i = i
4443
}

test/SILOptimizer/lifetime_dependence_diagnostics.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
struct BV : ~Escapable {
1111
let p: UnsafeRawPointer
1212
let c: Int
13-
@_unsafeNonescapableResult
14-
init(_ p: UnsafeRawPointer, _ c: Int) {
13+
init(_ p: UnsafeRawPointer, _ c: Int) -> dependsOn(p) Self {
1514
self.p = p
1615
self.c = c
1716
}

test/SILOptimizer/lifetime_dependence_inherit.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,21 @@ struct BV : ~Escapable {
1212
let p: UnsafeRawPointer
1313
let i: Int
1414

15+
init(_ p: UnsafeRawPointer, _ i: Int) -> dependsOn(p) Self {
16+
self.p = p
17+
self.i = i
18+
}
19+
1520
@_unsafeNonescapableResult
16-
init(_ p: UnsafeRawPointer, _ i: Int) {
21+
init(independent p: UnsafeRawPointer, _ i: Int) {
1722
self.p = p
1823
self.i = i
1924
}
2025

2126
consuming func derive() -> dependsOn(self) BV {
2227
// Technically, this "new" view does not depend on the 'view' argument.
2328
// This unsafely creates a new view with no dependence.
24-
return BV(self.p, self.i)
29+
return BV(independent: self.p, self.i)
2530
}
2631
}
2732

test/SILOptimizer/lifetime_dependence_inherit_fail.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,21 @@ struct BV : ~Escapable {
1212
let p: UnsafeRawPointer
1313
let i: Int
1414

15+
init(_ p: UnsafeRawPointer, _ i: Int) -> dependsOn(p) Self {
16+
self.p = p
17+
self.i = i
18+
}
19+
1520
@_unsafeNonescapableResult
16-
init(_ p: UnsafeRawPointer, _ i: Int) {
21+
init(independent p: UnsafeRawPointer, _ i: Int) {
1722
self.p = p
1823
self.i = i
1924
}
2025

2126
consuming func derive() -> dependsOn(self) BV {
2227
// Technically, this "new" view does not depend on the 'view' argument.
2328
// This unsafely creates a new view with no dependence.
24-
return BV(self.p, self.i)
29+
return BV(independent: self.p, self.i)
2530
}
2631
}
2732

test/SILOptimizer/lifetime_dependence_insertion.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ struct BV : ~Escapable {
1212
let p: UnsafeRawPointer
1313
let i: Int
1414

15-
@_unsafeNonescapableResult
16-
init(_ p: UnsafeRawPointer, _ i: Int) {
15+
init(_ p: UnsafeRawPointer, _ i: Int) -> dependsOn(p) Self {
1716
self.p = p
1817
self.i = i
1918
}

test/SILOptimizer/lifetime_dependence_mutate.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ struct MBV : ~Escapable, ~Copyable {
1212
let p: UnsafeMutableRawPointer
1313
let c: Int
1414

15-
@_unsafeNonescapableResult
16-
init(_ p: UnsafeMutableRawPointer, _ c: Int) {
15+
init(_ p: UnsafeMutableRawPointer, _ c: Int) -> dependsOn(p) Self {
1716
self.p = p
1817
self.c = c
1918
}

test/SILOptimizer/lifetime_dependence_optional.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
// Simply test that it is possible for a module to define a pseudo-Optional type without triggering any compiler errors.
1111

1212
public protocol ExpressibleByNilLiteral: ~Copyable & ~Escapable {
13+
// TODO: dependsOn(immortal)
1314
@_unsafeNonescapableResult
1415
init(nilLiteral: ())
1516
}
@@ -29,6 +30,7 @@ extension Nillable: Sendable where Wrapped: ~Copyable & ~Escapable & Sendable {
2930
extension Nillable: BitwiseCopyable where Wrapped: BitwiseCopyable { }
3031

3132
extension Nillable: ExpressibleByNilLiteral where Wrapped: ~Copyable & ~Escapable {
33+
// TODO: dependsOn(immortal)
3234
@_transparent
3335
@_unsafeNonescapableResult
3436
public init(nilLiteral: ()) {

0 commit comments

Comments
 (0)