Skip to content

Commit 538f274

Browse files
committed
[stdlib] Roll back generalization of the nil-coalescing operator ??
We cannot currently express its proper lifetime semantics: its result’s lifetime should depend on the intersection of the lifetime of the left argument and the lifetime of the result of the right argument. `@lifetime(optional, defaultValue.result)` is what we want, but the `.result` part is not currently expressible. (Tying the dependency on the closure argument itself may be a viable option, but we aren’t confident enough to ship it like that yet.)
1 parent 96fd749 commit 538f274

File tree

2 files changed

+15
-8
lines changed

2 files changed

+15
-8
lines changed

stdlib/public/core/Optional.swift

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -809,11 +809,15 @@ extension Optional where Wrapped: ~Copyable & ~Escapable {
809809
/// type as the `Wrapped` type of `optional`.
810810
@_transparent
811811
@_alwaysEmitIntoClient
812-
@lifetime(optional)
813-
public func ?? <T: ~Copyable & ~Escapable>(
812+
public func ?? <T: ~Copyable>(
814813
optional: consuming T?,
815-
defaultValue: @autoclosure () throws -> T // FIXME: typed throw
814+
defaultValue: @autoclosure () throws -> T // FIXME: typed throws
816815
) rethrows -> T {
816+
// FIXME: We want this to support nonescapable `T` types.
817+
// To implement that, we need to be able to express that the result's lifetime
818+
// is limited to the intersection of `optional` and the result of
819+
// `defaultValue`:
820+
// @lifetime(optional, defaultValue.result)
817821
switch consume optional {
818822
case .some(let value):
819823
return value
@@ -881,12 +885,15 @@ internal func _legacy_abi_optionalNilCoalescingOperator <T>(
881885
/// `optional` have the same type.
882886
@_transparent
883887
@_alwaysEmitIntoClient
884-
@lifetime(optional)
885-
// FIXME: This needs to support typed throws.
886-
public func ?? <T: ~Copyable & ~Escapable>(
888+
public func ?? <T: ~Copyable>(
887889
optional: consuming T?,
888-
defaultValue: @autoclosure () throws -> T?
890+
defaultValue: @autoclosure () throws -> T? // FIXME: typed throws
889891
) rethrows -> T? {
892+
// FIXME: We want this to support nonescapable `T` types.
893+
// To implement that, we need to be able to express that the result's lifetime
894+
// is limited to the intersection of `optional` and the result of
895+
// `defaultValue`:
896+
// @lifetime(optional, defaultValue.result)
890897
switch consume optional {
891898
case .some(let value):
892899
return value

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ Constructor UnsafeRawPointer.init(_:) has generic signature change from <T> to <
233233
Enum MemoryLayout has generic signature change from <T> to <T where T : ~Copyable, T : ~Escapable>
234234
Enum Optional has generic signature change from <Wrapped> to <Wrapped where Wrapped : ~Copyable, Wrapped : ~Escapable>
235235
Enum Result has generic signature change from <Success, Failure where Failure : Swift.Error> to <Success, Failure where Failure : Swift.Error, Success : ~Copyable, Success : ~Escapable>
236-
Func ??(_:_:) has generic signature change from <T> to <T where T : ~Copyable, T : ~Escapable>
236+
Func ??(_:_:) has generic signature change from <T> to <T where T : ~Copyable>
237237
Func ??(_:_:) has parameter 0 changing from Default to Owned
238238
Func ManagedBuffer.create(minimumCapacity:makingHeaderWith:) has generic signature change from <Header, Element> to <Header, Element where Element : ~Copyable>
239239
Func ManagedBufferPointer.isUniqueReference() has generic signature change from <Header, Element> to <Header, Element where Element : ~Copyable>

0 commit comments

Comments
 (0)