Skip to content

Commit 192b404

Browse files
committed
[stdlib] Work around ~Escapable breaking Optional.init syntax
1 parent b17a8d4 commit 192b404

File tree

4 files changed

+51
-7
lines changed

4 files changed

+51
-7
lines changed

stdlib/public/core/Optional.swift

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,12 +162,29 @@ where Wrapped: ~Copyable & ~Escapable {
162162
}
163163
}
164164

165-
extension Optional where Wrapped: ~Copyable & ~Escapable {
165+
extension Optional where Wrapped: ~Copyable {
166166
/// Creates an instance that stores the given value.
167167
@_transparent
168168
@_preInverseGenerics
169-
@lifetime(some)
170-
public init(_ some: consuming Wrapped) { self = .some(some) }
169+
public init(_ value: consuming Wrapped) {
170+
// FIXME: Merge this with the generalization below.
171+
// This is the original initializer, preserved to avoid breaking source
172+
// compatibility with clients that use the `Optional.init` syntax to create
173+
// a function reference. The ~Escapable generalization is currently breaking
174+
// that. (rdar://147533059)
175+
self = .some(value)
176+
}
177+
}
178+
179+
extension Optional where Wrapped: ~Copyable & ~Escapable {
180+
/// Creates an instance that stores the given value.
181+
@_transparent
182+
@_alwaysEmitIntoClient
183+
@lifetime(value)
184+
public init(_ value: consuming Wrapped) {
185+
// FIXME: Merge this into the original entry above.
186+
self = .some(value)
187+
}
171188
}
172189

173190
extension Optional {

test/api-digester/Outputs/stability-stdlib-source-base.swift.expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ Constructor ExpressibleByNilLiteral.init(nilLiteral:) has generic signature chan
216216
Constructor ManagedBufferPointer.init(bufferClass:minimumCapacity:makingHeaderWith:) has generic signature change from <Header, Element> to <Header, Element where Element : ~Copyable>
217217
Constructor ManagedBufferPointer.init(unsafeBufferObject:) has generic signature change from <Header, Element> to <Header, Element where Element : ~Copyable>
218218
Constructor OpaquePointer.init(_:) has generic signature change from <T> to <T where T : ~Copyable>
219-
Constructor Optional.init(_:) has generic signature change from <Wrapped> to <Wrapped where Wrapped : ~Copyable, Wrapped : ~Escapable>
219+
Constructor Optional.init(_:) has generic signature change from <Wrapped> to <Wrapped where Wrapped : ~Copyable>
220220
Constructor Optional.init(_:) has parameter 0 changing from Default to Owned
221221
Constructor Optional.init(nilLiteral:) has generic signature change from <Wrapped> to <Wrapped where Wrapped : ~Copyable, Wrapped : ~Escapable>
222222
Constructor Result.init(catching:) has generic signature change from <Success, Failure where Failure == any Swift.Error> to <Success, Failure where Failure : Swift.Error, Success : ~Copyable>

test/api-digester/stability-stdlib-abi-without-asserts.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,8 @@ Constructor OpaquePointer.init(_:) has generic signature change from <T> to <T w
477477
Constructor OpaquePointer.init(_:) has mangled name changing from 'Swift.OpaquePointer.init<A>(Swift.Optional<Swift.UnsafePointer<A>>) -> Swift.Optional<Swift.OpaquePointer>' to 'Swift.OpaquePointer.init<A where A: ~Swift.Copyable>(Swift.Optional<Swift.UnsafePointer<A>>) -> Swift.Optional<Swift.OpaquePointer>'
478478
Constructor OpaquePointer.init(_:) has mangled name changing from 'Swift.OpaquePointer.init<A>(Swift.UnsafePointer<A>) -> Swift.OpaquePointer' to 'Swift.OpaquePointer.init<A where A: ~Swift.Copyable>(Swift.UnsafePointer<A>) -> Swift.OpaquePointer'
479479
Constructor OpaquePointer.init(_:) is now with @_preInverseGenerics
480-
Constructor Optional.init(_:) has generic signature change from <Wrapped> to <Wrapped where Wrapped : ~Copyable, Wrapped : ~Escapable>
481-
Constructor Optional.init(_:) has mangled name changing from 'Swift.Optional.init(A) -> Swift.Optional<A>' to '(extension in Swift):Swift.Optional< where A: ~Swift.Copyable, A: ~Swift.Escapable>.init(A) -> Swift.Optional<A>'
480+
Constructor Optional.init(_:) has generic signature change from <Wrapped> to <Wrapped where Wrapped : ~Copyable>
481+
Constructor Optional.init(_:) has mangled name changing from 'Swift.Optional.init(A) -> Swift.Optional<A>' to '(extension in Swift):Swift.Optional< where A: ~Swift.Copyable>.init(A) -> Swift.Optional<A>'
482482
Constructor Optional.init(_:) has parameter 0 changing from Default to Owned
483483
Constructor Optional.init(_:) is now with @_preInverseGenerics
484484
Constructor Optional.init(nilLiteral:) has generic signature change from <Wrapped> to <Wrapped where Wrapped : ~Copyable, Wrapped : ~Escapable>

test/stdlib/OptionalGeneralizations.swift

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
// RUN: %target-run-simple-swift(-enable-experimental-feature NonescapableTypes)
1+
// RUN: %target-run-simple-swift(-enable-experimental-feature NonescapableTypes -enable-experimental-feature LifetimeDependence)
22
// REQUIRES: executable_test
33
// REQUIRES: reflection
44
// REQUIRES: swift_feature_NonescapableTypes
5+
// REQUIRES: swift_feature_LifetimeDependence
56

67
import StdlibUnittest
78
import Swift
@@ -65,3 +66,29 @@ suite.test("Escapability") {
6566
expectFalse(isEscapable(Optional<NonescapableNontrivialStruct>.self))
6667
}
6768
#endif
69+
70+
func apply<T, U>(
71+
_ input: T,
72+
_ body: (T) -> U
73+
) -> U {
74+
body(input)
75+
}
76+
77+
func apply2<T: ~Copyable, U: ~Copyable>(
78+
_ input: consuming T,
79+
_ body: (consuming T) -> U
80+
) -> U {
81+
body(input)
82+
}
83+
84+
suite.test("Initializer references") {
85+
do {
86+
let r = apply(TrivialStruct(), Optional.init)
87+
expectTrue(r != nil)
88+
}
89+
90+
do {
91+
let r = apply2(NoncopyableStruct(), Optional.init)
92+
expectTrue(r != nil)
93+
}
94+
}

0 commit comments

Comments
 (0)