From cae45f1584b5e73534598666656f9bee80d9c304 Mon Sep 17 00:00:00 2001 From: Guillaume Lessard Date: Wed, 30 Apr 2025 15:54:41 -0700 Subject: [PATCH 1/4] [stdlib] make `_overrideLifetime` functions public These are discussed in the lifetime annotations pitch: https://github.com/swiftlang/swift-evolution/pull/2750 Addresses rdar://150400414 --- stdlib/public/core/LifetimeManager.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stdlib/public/core/LifetimeManager.swift b/stdlib/public/core/LifetimeManager.swift index eeaeba32b2484..c8c555efb926e 100644 --- a/stdlib/public/core/LifetimeManager.swift +++ b/stdlib/public/core/LifetimeManager.swift @@ -290,7 +290,7 @@ public func _copy(_ value: T) -> T { @_alwaysEmitIntoClient @_transparent @lifetime(borrow source) -internal func _overrideLifetime< +public func _overrideLifetime< T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable >( _ dependent: consuming T, borrowing source: borrowing U @@ -308,7 +308,7 @@ internal func _overrideLifetime< @_alwaysEmitIntoClient @_transparent @lifetime(copy source) -internal func _overrideLifetime< +public func _overrideLifetime< T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable >( _ dependent: consuming T, copying source: borrowing U @@ -326,7 +326,7 @@ internal func _overrideLifetime< @_alwaysEmitIntoClient @_transparent @lifetime(&source) -internal func _overrideLifetime< +public func _overrideLifetime< T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable >( _ dependent: consuming T, From 74766a924cf83d944181b9150e41921ae74116d4 Mon Sep 17 00:00:00 2001 From: Guillaume Lessard Date: Wed, 30 Apr 2025 16:01:46 -0700 Subject: [PATCH 2/4] [test] use the stdlib _overrideLifetime functions --- test/SILOptimizer/Inputs/SpanExtras.swift | 51 ----------------------- 1 file changed, 51 deletions(-) diff --git a/test/SILOptimizer/Inputs/SpanExtras.swift b/test/SILOptimizer/Inputs/SpanExtras.swift index 881ac3d998b26..29ddeb2817d39 100644 --- a/test/SILOptimizer/Inputs/SpanExtras.swift +++ b/test/SILOptimizer/Inputs/SpanExtras.swift @@ -1,56 +1,5 @@ import Builtin -/// Unsafely discard any lifetime dependency on the `dependent` argument. Return -/// a value identical to `dependent` with a lifetime dependency on the caller's -/// borrow scope of the `source` argument. -@unsafe -@_unsafeNonescapableResult -@_alwaysEmitIntoClient -@_transparent -@lifetime(borrow source) -internal func _overrideLifetime< - T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable ->( - _ dependent: consuming T, borrowing source: borrowing U -) -> T { - // TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence - // should be expressed by a builtin that is hidden within the function body. - dependent -} - -/// Unsafely discard any lifetime dependency on the `dependent` argument. Return -/// a value identical to `dependent` that inherits all lifetime dependencies from -/// the `source` argument. -@unsafe -@_unsafeNonescapableResult -@_alwaysEmitIntoClient -@_transparent -@lifetime(copy source) -internal func _overrideLifetime< - T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable ->( - _ dependent: consuming T, copying source: borrowing U -) -> T { - // TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence - // should be expressed by a builtin that is hidden within the function body. - dependent -} - -@unsafe -@_unsafeNonescapableResult -@_alwaysEmitIntoClient -@_transparent -@lifetime(&source) -internal func _overrideLifetime< - T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable ->( - _ dependent: consuming T, mutating source: inout U -) -> T { - // TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence - // should be expressed by a builtin that is hidden within the function body. - dependent -} - // A MutableSpan represents a span of memory which // contains initialized `Element` instances. @frozen From 2942637f4addf7d020e03085d057e2d521cfd570 Mon Sep 17 00:00:00 2001 From: Guillaume Lessard Date: Tue, 6 May 2025 14:47:35 -0700 Subject: [PATCH 3/4] [stdlib] remove TODOs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These TODOs aren’t particularly actionable. What we really want is a way to define `_overrideLifetime()` in a not-unsafe way, and that will probably be a `Builtin` operation. --- stdlib/public/core/LifetimeManager.swift | 6 ------ 1 file changed, 6 deletions(-) diff --git a/stdlib/public/core/LifetimeManager.swift b/stdlib/public/core/LifetimeManager.swift index c8c555efb926e..4939333732dfc 100644 --- a/stdlib/public/core/LifetimeManager.swift +++ b/stdlib/public/core/LifetimeManager.swift @@ -295,8 +295,6 @@ public func _overrideLifetime< >( _ dependent: consuming T, borrowing source: borrowing U ) -> T { - // TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence - // should be expressed by a builtin that is hidden within the function body. dependent } @@ -313,8 +311,6 @@ public func _overrideLifetime< >( _ dependent: consuming T, copying source: borrowing U ) -> T { - // TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence - // should be expressed by a builtin that is hidden within the function body. dependent } @@ -332,7 +328,5 @@ public func _overrideLifetime< _ dependent: consuming T, mutating source: inout U ) -> T { - // TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence - // should be expressed by a builtin that is hidden within the function body. dependent } From ca8fc0ec04ee477aed472e48b2746d4ac8b72693 Mon Sep 17 00:00:00 2001 From: Guillaume Lessard Date: Wed, 30 Apr 2025 17:44:10 -0700 Subject: [PATCH 4/4] [test] remove more copies of `_overrideLifetime()` --- .../Inputs/lifetime_dependence.swift | 18 -------- ...licit_lifetime_dependence_specifiers.swift | 24 ----------- test/SIL/implicit_lifetime_dependence.swift | 24 ----------- ...fetime_dependence_span_lifetime_attr.swift | 24 ----------- .../addressable_dependencies.swift | 8 ---- .../dependence_insertion.swift | 13 ------ .../lifetime_dependence_mutate.swift | 42 ------------------ .../lifetime_dependence/semantics.swift | 43 ------------------- 8 files changed, 196 deletions(-) diff --git a/test/ModuleInterface/Inputs/lifetime_dependence.swift b/test/ModuleInterface/Inputs/lifetime_dependence.swift index 8c04ab6867d72..8ffdaf1e82090 100644 --- a/test/ModuleInterface/Inputs/lifetime_dependence.swift +++ b/test/ModuleInterface/Inputs/lifetime_dependence.swift @@ -1,21 +1,3 @@ -@_unsafeNonescapableResult -@_alwaysEmitIntoClient -@_transparent -@lifetime(borrow source) -internal func _overrideLifetime( - _ dependent: consuming T, borrowing source: borrowing U) -> T { - dependent -} - -@_unsafeNonescapableResult -@_alwaysEmitIntoClient -@_transparent -@lifetime(copy source) -internal func _overrideLifetime( - _ dependent: consuming T, copying source: borrowing U) -> T { - dependent -} - public struct AnotherView : ~Escapable { @usableFromInline let _ptr: UnsafeRawBufferPointer @usableFromInline let _count: Int diff --git a/test/SIL/explicit_lifetime_dependence_specifiers.swift b/test/SIL/explicit_lifetime_dependence_specifiers.swift index 1d74064d689ca..4872d19ab6a9b 100644 --- a/test/SIL/explicit_lifetime_dependence_specifiers.swift +++ b/test/SIL/explicit_lifetime_dependence_specifiers.swift @@ -8,30 +8,6 @@ import Builtin -@_unsafeNonescapableResult -@lifetime(borrow source) -internal func _overrideLifetime< - T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable ->( - _ dependent: consuming T, borrowing source: borrowing U -) -> T { - // TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence - // should be expressed by a builtin that is hidden within the function body. - dependent -} - -@_unsafeNonescapableResult -@lifetime(copy source) -internal func _overrideLifetime< - T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable ->( - _ dependent: consuming T, copying source: borrowing U -) -> T { - // TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence - // should be expressed by a builtin that is hidden within the function body. - dependent -} - struct BufferView : ~Escapable { let ptr: UnsafeRawBufferPointer // CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers10BufferViewVyACSWcfC : $@convention(method) (UnsafeRawBufferPointer, @thin BufferView.Type) -> @lifetime(borrow 0) @owned BufferView { diff --git a/test/SIL/implicit_lifetime_dependence.swift b/test/SIL/implicit_lifetime_dependence.swift index 181235c3b7daa..c70d5ddccb408 100644 --- a/test/SIL/implicit_lifetime_dependence.swift +++ b/test/SIL/implicit_lifetime_dependence.swift @@ -5,30 +5,6 @@ // REQUIRES: swift_feature_LifetimeDependence -@_unsafeNonescapableResult -@lifetime(borrow source) -internal func _overrideLifetime< - T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable ->( - _ dependent: consuming T, borrowing source: borrowing U -) -> T { - // TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence - // should be expressed by a builtin that is hidden within the function body. - dependent -} - -@_unsafeNonescapableResult -@lifetime(copy source) -internal func _overrideLifetime< - T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable ->( - _ dependent: consuming T, copying source: borrowing U -) -> T { - // TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence - // should be expressed by a builtin that is hidden within the function body. - dependent -} - struct BufferView : ~Escapable { let ptr: UnsafeRawBufferPointer let c: Int diff --git a/test/SIL/lifetime_dependence_span_lifetime_attr.swift b/test/SIL/lifetime_dependence_span_lifetime_attr.swift index 4d478b19b2523..8771b788a3b2d 100644 --- a/test/SIL/lifetime_dependence_span_lifetime_attr.swift +++ b/test/SIL/lifetime_dependence_span_lifetime_attr.swift @@ -5,30 +5,6 @@ // REQUIRES: swift_in_compiler // REQUIRES: swift_feature_LifetimeDependence -@_unsafeNonescapableResult -@lifetime(borrow source) -internal func _overrideLifetime< - T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable ->( - _ dependent: consuming T, borrowing source: borrowing U -) -> T { - // TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence - // should be expressed by a builtin that is hidden within the function body. - dependent -} - -@_unsafeNonescapableResult -@lifetime(copy source) -internal func _overrideLifetime< - T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable ->( - _ dependent: consuming T, copying source: borrowing U -) -> T { - // TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence - // should be expressed by a builtin that is hidden within the function body. - dependent -} - // TODO: Use real Range public struct FakeRange { public let lowerBound: Bound diff --git a/test/SILOptimizer/addressable_dependencies.swift b/test/SILOptimizer/addressable_dependencies.swift index 2b05f43d757db..a9a54f51cdf12 100644 --- a/test/SILOptimizer/addressable_dependencies.swift +++ b/test/SILOptimizer/addressable_dependencies.swift @@ -6,14 +6,6 @@ import Builtin -// Copied from the stdlib until we have Builtin.overrideLifetime. -@_unsafeNonescapableResult -@lifetime(borrow source) -internal func _overrideLifetime( - _ dependent: consuming T, borrowing source: borrowing U) -> T { - dependent -} - struct NodeRef: ~Escapable { private var parent: UnsafePointer diff --git a/test/SILOptimizer/lifetime_dependence/dependence_insertion.swift b/test/SILOptimizer/lifetime_dependence/dependence_insertion.swift index f3cf707c6e9b4..0fc2b1578bec0 100644 --- a/test/SILOptimizer/lifetime_dependence/dependence_insertion.swift +++ b/test/SILOptimizer/lifetime_dependence/dependence_insertion.swift @@ -17,19 +17,6 @@ import Builtin -@unsafe -@_unsafeNonescapableResult -@_alwaysEmitIntoClient -@_transparent -@lifetime(borrow source) -internal func _overrideLifetime< - T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable ->( - _ dependent: consuming T, borrowing source: borrowing U -) -> T { - dependent -} - struct BV : ~Escapable { let p: UnsafeRawPointer let i: Int diff --git a/test/SILOptimizer/lifetime_dependence/lifetime_dependence_mutate.swift b/test/SILOptimizer/lifetime_dependence/lifetime_dependence_mutate.swift index e880a0dac7d07..0f7f361bd694e 100644 --- a/test/SILOptimizer/lifetime_dependence/lifetime_dependence_mutate.swift +++ b/test/SILOptimizer/lifetime_dependence/lifetime_dependence_mutate.swift @@ -8,48 +8,6 @@ // REQUIRES: swift_in_compiler // REQUIRES: swift_feature_LifetimeDependence -/// Unsafely discard any lifetime dependency on the `dependent` argument. Return -/// a value identical to `dependent` with a lifetime dependency on the caller's -/// borrow scope of the `source` argument. -@_unsafeNonescapableResult -@_transparent -@lifetime(borrow source) -internal func _overrideLifetime< - T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable ->( - _ dependent: consuming T, borrowing source: borrowing U -) -> T { - dependent -} - -/// Unsafely discard any lifetime dependency on the `dependent` argument. Return -/// a value identical to `dependent` that inherits all lifetime dependencies from -/// the `source` argument. -@_unsafeNonescapableResult -@_transparent -@lifetime(copy source) -internal func _overrideLifetime< - T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable ->( - _ dependent: consuming T, copying source: borrowing U -) -> T { - dependent -} - -/// Unsafely discard any lifetime dependency on the `dependent` argument. Return -/// a value identical to `dependent` that inherits all lifetime dependencies from -/// the `source` argument. -@_unsafeNonescapableResult -@_transparent -@lifetime(&source) -internal func _overrideLifetime< - T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable ->( - _ dependent: consuming T, mutating source: inout U -) -> T { - dependent -} - struct MutableSpan : ~Escapable, ~Copyable { let base: UnsafeMutableRawPointer let count: Int diff --git a/test/SILOptimizer/lifetime_dependence/semantics.swift b/test/SILOptimizer/lifetime_dependence/semantics.swift index 7a2e012532932..1d98624cfaabf 100644 --- a/test/SILOptimizer/lifetime_dependence/semantics.swift +++ b/test/SILOptimizer/lifetime_dependence/semantics.swift @@ -15,49 +15,6 @@ import Builtin -@_unsafeNonescapableResult -@_transparent -@lifetime(borrow source) -internal func _overrideLifetime< - T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable ->( - _ dependent: consuming T, borrowing source: borrowing U -) -> T { - // TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence - // should be expressed by a builtin that is hidden within the function body. - dependent -} - -/// Unsafely discard any lifetime dependency on the `dependent` argument. Return -/// a value identical to `dependent` that inherits all lifetime dependencies from -/// the `source` argument. -@_unsafeNonescapableResult -@_transparent -@lifetime(copy source) -internal func _overrideLifetime< - T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable ->( - _ dependent: consuming T, copying source: borrowing U -) -> T { - // TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence - // should be expressed by a builtin that is hidden within the function body. - dependent -} - -/// Unsafely discard any lifetime dependency on the `dependent` argument. Return -/// a value identical to `dependent` that inherits all lifetime dependencies from -/// the `source` argument. -@_unsafeNonescapableResult -@_transparent -@lifetime(&source) -internal func _overrideLifetime< - T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable ->( - _ dependent: consuming T, mutating source: inout U -) -> T { - dependent -} - struct NotEscapable: ~Escapable {} // Lifetime dependence semantics by example.