Skip to content

Commit a9f22a4

Browse files
committed
LifetimeDependenceDiagnostics; remove a bootstrapping hack.
This temporary hack was preventing diagnostics from kicking in. This could even result in invalid SIL after the diagnostic failed to trigger.
1 parent 0326c98 commit a9f22a4

File tree

7 files changed

+88
-41
lines changed

7 files changed

+88
-41
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LifetimeDependenceDiagnostics.swift

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -199,21 +199,6 @@ private struct DiagnoseDependence {
199199
if function.hasUnsafeNonEscapableResult {
200200
return .continueWalk
201201
}
202-
// FIXME: remove this condition once we have a Builtin.dependence,
203-
// which developers should use to model the unsafe
204-
// dependence. Builtin.lifetime_dependence will be lowered to
205-
// mark_dependence [unresolved], which will be checked
206-
// independently. Instead, of this function result check, allow
207-
// isUnsafeApplyResult to be used be mark_dependence [unresolved]
208-
// without checking its dependents.
209-
//
210-
// Allow returning an apply result (@_unsafeNonescapableResult) if
211-
// the calling function has a dependence. This implicitly makes
212-
// the unsafe nonescapable result dependent on the calling
213-
// function's lifetime dependence arguments.
214-
if dependence.isUnsafeApplyResult, function.hasResultDependence {
215-
return .continueWalk
216-
}
217202
// Check that the parameter dependence for this result is the same
218203
// as the current dependence scope.
219204
if let arg = dependence.scope.parentValue as? FunctionArgument,

SwiftCompilerSources/Sources/Optimizer/Utilities/LifetimeDependenceUtils.swift

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -225,16 +225,6 @@ extension LifetimeDependence {
225225
self.dependentValue = value
226226
}
227227

228-
var isUnsafeApplyResult: Bool {
229-
if case let .owned(value) = scope {
230-
if let apply = value.definingInstruction as? FullApplySite {
231-
assert(!apply.hasResultDependence)
232-
return true
233-
}
234-
}
235-
return false
236-
}
237-
238228
/// Construct LifetimeDependence from mark_dependence [unresolved] or mark_dependence [nonescaping].
239229
///
240230
/// For any LifetimeDependence constructed from a mark_dependence, its `dependentValue` will be the result of the

test/SIL/explicit_lifetime_dependence_specifiers.swift

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,30 @@
88

99
import Builtin
1010

11+
@_unsafeNonescapableResult
12+
@lifetime(borrow source)
13+
internal func _overrideLifetime<
14+
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
15+
>(
16+
_ dependent: consuming T, borrowing source: borrowing U
17+
) -> T {
18+
// TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence
19+
// should be expressed by a builtin that is hidden within the function body.
20+
dependent
21+
}
22+
23+
@_unsafeNonescapableResult
24+
@lifetime(source)
25+
internal func _overrideLifetime<
26+
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
27+
>(
28+
_ dependent: consuming T, copying source: borrowing U
29+
) -> T {
30+
// TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence
31+
// should be expressed by a builtin that is hidden within the function body.
32+
dependent
33+
}
34+
1135
struct BufferView : ~Escapable {
1236
let ptr: UnsafeRawBufferPointer
1337
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers10BufferViewVyACSWcfC : $@convention(method) (UnsafeRawBufferPointer, @thin BufferView.Type) -> @lifetime(borrow 0) @owned BufferView {
@@ -22,7 +46,7 @@ struct BufferView : ~Escapable {
2246
}
2347
self.ptr = ptr
2448
}
25-
@_unsafeNonescapableResult
49+
@lifetime(borrow ptr)
2650
init(independent ptr: UnsafeRawBufferPointer) {
2751
self.ptr = ptr
2852
}
@@ -71,7 +95,8 @@ func derive(_ x: borrowing BufferView) -> BufferView {
7195
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers16consumeAndCreateyAA10BufferViewVADnF : $@convention(thin) (@owned BufferView) -> @lifetime(copy 0) @owned BufferView {
7296
@lifetime(x)
7397
func consumeAndCreate(_ x: consuming BufferView) -> BufferView {
74-
return BufferView(independent: x.ptr)
98+
let bv = BufferView(independent: x.ptr)
99+
return _overrideLifetime(bv, copying: x)
75100
}
76101

77102
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers17deriveThisOrThat1yAA10BufferViewVAD_ADtF : $@convention(thin) (@guaranteed BufferView, @guaranteed BufferView) -> @lifetime(copy 1, borrow 0) @owned BufferView {
@@ -89,7 +114,8 @@ func deriveThisOrThat2(_ this: borrowing BufferView, _ that: consuming BufferVie
89114
if (Int.random(in: 1..<100) == 0) {
90115
return BufferView(independent: this.ptr)
91116
}
92-
return BufferView(independent: that.ptr)
117+
let bv = BufferView(independent: that.ptr)
118+
return _overrideLifetime(bv, copying: that)
93119
}
94120

95121
func use(_ x: borrowing BufferView) {}
@@ -123,12 +149,12 @@ struct Container : ~Escapable {
123149
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers16getConsumingViewyAA06BufferG0VAA9ContainerVnF : $@convention(thin) (@owned Container) -> @lifetime(copy 0) @owned BufferView {
124150
@lifetime(x)
125151
func getConsumingView(_ x: consuming Container) -> BufferView {
126-
return BufferView(independent: x.ptr)
152+
let bv = BufferView(independent: x.ptr)
153+
return _overrideLifetime(bv, copying: x)
127154
}
128155

129156
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers16getBorrowingViewyAA06BufferG0VAA9ContainerVF : $@convention(thin) (@guaranteed Container) -> @lifetime(borrow 0) @owned BufferView {
130157
@lifetime(borrow x)
131158
func getBorrowingView(_ x: borrowing Container) -> BufferView {
132159
return BufferView(independent: x.ptr)
133160
}
134-

test/SIL/implicit_lifetime_dependence.swift

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,27 @@
55

66
// REQUIRES: swift_feature_LifetimeDependence
77

8+
@_unsafeNonescapableResult
9+
@lifetime(borrow source)
10+
internal func _overrideLifetime<
11+
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
12+
>(
13+
_ dependent: consuming T, borrowing source: borrowing U
14+
) -> T {
15+
// TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence
16+
// should be expressed by a builtin that is hidden within the function body.
17+
dependent
18+
}
19+
820
@_unsafeNonescapableResult
921
@lifetime(source)
10-
func unsafeLifetime<T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable>(
11-
dependent: consuming T, dependsOn source: borrowing U)
12-
-> T {
22+
internal func _overrideLifetime<
23+
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
24+
>(
25+
_ dependent: consuming T, copying source: borrowing U
26+
) -> T {
27+
// TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence
28+
// should be expressed by a builtin that is hidden within the function body.
1329
dependent
1430
}
1531

@@ -21,7 +37,7 @@ struct BufferView : ~Escapable {
2137
self.ptr = ptr
2238
self.c = c
2339
}
24-
@_unsafeNonescapableResult
40+
@lifetime(borrow ptr)
2541
init(independent ptr: UnsafeRawBufferPointer, _ c: Int) {
2642
self.ptr = ptr
2743
self.c = c
@@ -74,7 +90,8 @@ func derive(_ unused: Int, _ x: borrowing BufferView) -> BufferView {
7490

7591
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence16consumeAndCreateyAA10BufferViewVADnF : $@convention(thin) (@owned BufferView) -> @lifetime(copy 0) @owned BufferView {
7692
func consumeAndCreate(_ x: consuming BufferView) -> BufferView {
77-
return BufferView(independent: x.ptr, x.c)
93+
let bv = BufferView(independent: x.ptr, x.c)
94+
return _overrideLifetime(bv, copying: x)
7895
}
7996

8097
func use(_ x: borrowing BufferView) {}
@@ -175,7 +192,7 @@ struct GenericBufferView<Element> : ~Escapable {
175192
count: bounds.upperBound.distance(to:bounds.lowerBound) / MemoryLayout<Element>.stride
176193
)
177194
// assuming that bounds is within self
178-
return unsafeLifetime(dependent: result, dependsOn: self)
195+
return _overrideLifetime(result, copying: self)
179196
}
180197
}
181198
}

test/SIL/lifetime_dependence_generics.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ extension P {
2121
}
2222

2323
public struct View: ~Escapable {
24-
// TODO: dependsOn(immortal)
25-
@_unsafeNonescapableResult
24+
@lifetime(immortal)
2625
init() { }
2726
}
2827

2928
public struct PView: P {
29+
@lifetime(immortal)
3030
borrowing func getE() -> View { return View() }
3131
}
3232

@@ -36,7 +36,7 @@ public func test(pview: borrowing PView) -> View {
3636

3737
// CHECK-LABEL: sil hidden @$s28lifetime_dependence_generics1PPAAE10getDefault1EQzyF : $@convention(method) <Self where Self : P> (@in_guaranteed Self) -> @lifetime(borrow 0) @out Self.E {
3838

39-
// CHECK-LABEL: sil hidden @$s28lifetime_dependence_generics5PViewV4getEAA4ViewVyF : $@convention(method) (PView) -> @lifetime(borrow 0) @owned View {
39+
// CHECK-LABEL: sil hidden @$s28lifetime_dependence_generics5PViewV4getEAA4ViewVyF : $@convention(method) (PView) -> @lifetime(immortal) @owned View {
4040

4141
// CHECK-LABEL: sil private [transparent] [thunk] @$s28lifetime_dependence_generics5PViewVAA1PA2aDP4getE1EQzyFTW : $@convention(witness_method: P) (@in_guaranteed PView) -> @lifetime(borrow 0) @out View {
4242

test/SIL/lifetime_dependence_span_lifetime_attr.swift

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,30 @@
55
// REQUIRES: swift_in_compiler
66
// REQUIRES: swift_feature_LifetimeDependence
77

8+
@_unsafeNonescapableResult
9+
@lifetime(borrow source)
10+
internal func _overrideLifetime<
11+
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
12+
>(
13+
_ dependent: consuming T, borrowing source: borrowing U
14+
) -> T {
15+
// TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence
16+
// should be expressed by a builtin that is hidden within the function body.
17+
dependent
18+
}
19+
20+
@_unsafeNonescapableResult
21+
@lifetime(source)
22+
internal func _overrideLifetime<
23+
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
24+
>(
25+
_ dependent: consuming T, copying source: borrowing U
26+
) -> T {
27+
// TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence
28+
// should be expressed by a builtin that is hidden within the function body.
29+
dependent
30+
}
31+
832
// TODO: Use real Range
933
public struct FakeRange<Bound> {
1034
public let lowerBound: Bound
@@ -128,10 +152,11 @@ extension Span {
128152
public subscript(bounds: FakeRange<SpanIndex<Element>>) -> Self {
129153
@lifetime(self)
130154
get {
131-
Span(
155+
let span = Span(
132156
start: bounds.lowerBound,
133157
count: bounds.upperBound.distance(to:bounds.lowerBound) / MemoryLayout<Element>.stride
134158
)
159+
return _overrideLifetime(span, copying: self)
135160
}
136161
}
137162

test/SILOptimizer/lifetime_dependence/lifetime_dependence_borrow_fail.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,17 @@ struct NC : ~Copyable {
3131
BV(p, i)
3232
}
3333
34+
// @lifetime(borrow self)
3435
borrowing func getEmpty() -> Empty {
3536
Empty()
3637
}
3738
}
3839
3940
// Test dependencies on an empty struct.
40-
public struct Empty: ~Escapable {}
41+
public struct Empty: ~Escapable {
42+
@lifetime(immortal)
43+
init() {}
44+
}
4145
4246
func use(e: Empty) {}
4347

0 commit comments

Comments
 (0)