Open
Description
Description
An inout
parameter of an Optional
of a type that is ~Copyable & ~Escapable
is very hard to work with. In particular, the idiomatic way to unwrap that parameter doesn't work.
Reproduction
Using swift-DEVELOPMENT-SNAPSHOT-2025-06-01-a (e.g. in godbolt)
func modify<T, U>(
_ s: inout MutableSpan<T>?,
_ body: (inout MutableSpan<T>) -> U
) -> U {
var unwrapped: MutableSpan<T>
if let uw = s {
unwrapped = uw
} else {
unwrapped = MutableSpan(_unsafeElements: .init(start: nil, count: 0))
}
let u = body(&unwrapped)
s = consume unwrapped
return u
}
Does not compile. The error is:
<source>:5:9: error: lifetime-dependent variable 'unwrapped' escapes its scope
3 | _ body: (inout MutableSpan<T>) -> U
4 | ) -> U {
5 | var unwrapped: MutableSpan<T>
| `- error: lifetime-dependent variable 'unwrapped' escapes its scope
6 | if let uw = s {
7 | unwrapped = uw
8 | } else {
9 | unwrapped = MutableSpan(_unsafeElements: .init(start: nil, count: 0))
| `- note: it depends on the lifetime of this parent value
10 | }
11 | let u = body(&unwrapped)
12 | s = consume unwrapped
| `- note: this use causes the lifetime-dependent value to escape
13 | return u
14 | }
Compiler returned: 1
Expected behavior
This should compile. In fact, modifying line 6 to read if let uw = s.take() {
allows the whole thing to compile. That changes things very little, yet satisfies the compiler.
Environment
Swift version 6.2-dev (LLVM 5e7837820b1c886, Swift d5ef256)
Target: x86_64-unknown-linux-gnu
Build config: +assertions
The compiler is called with -enable-experimental-feature LifetimeDependence
Additional information
rdar://152572002