A bug with `Optional` in Swift 6.2

Hey guys!

When switching from Swift 6.0 to new Swift version 6.2 (bundled with Xcode 26 beta 2) I noticed a weird error:

<unknown>:0: error: lifetime-dependent variable '$implicit_value' escapes its scope

Screenshot below:

It took me some time, but I found out the code part which makes this error:

/// An abstraction for `Optional<Wrapped>`.
public protocol OptionalProtocol: ExpressibleByNilLiteral {

    associatedtype Wrapped

    static var none: Self { get }
    static func some(_ value: Wrapped) -> Self

    /// Unwraps optional.
    /// - Returns: Unwrapped value.
    func unwrapped() throws -> Wrapped
}

and usage of this protocol in:

extension Optional: OptionalProtocol {

    /// Unwraps optional and throws error when `nil` encountered.
    /// - Returns: Unwrapped value.
    public func unwrapped() throws -> Wrapped {
        switch self {
        case .none: throw Self.Error.nullValue
        case .some(let wrapped): return wrapped
        }
    }

    public enum Error: Swift.Error {
        case nullValue
    }
}

EDIT
I have noticed this line is causing the real problem:

static func some(_ value: Wrapped) -> Self

/EDIT

The OptionalProtocol abstraction is used in many places in my code at foundation level of my app (like formatters, property wrappers)

I assume it might be related with ~Copyable and ~Escapable conformance, so I did changes but without success:

1st approach

Add constraints to Wrapped of OptionalProtocol:

public protocol OptionalProtocol: ExpressibleByNilLiteral where Wrapped: ~Copyable, Wrapped: ~Escapable { ...

This code has returned me followed error:

Cannot suppress 'Copyable' requirement of an associated type

2nd approach

Bypass previous error with protocol aggregator:

public protocol OptionalProtocol: ExpressibleByNilLiteral where Wrapped: OptionalWrapped {

    associatedtype Wrapped

    static var none: Self { get }
    static func some(_ value: Wrapped) -> Self

    /// Unwraps optional.
    /// - Returns: Unwrapped value.
    func unwrapped() throws -> Wrapped
}

public protocol OptionalWrapped: ~Copyable, ~Escapable { }

This code has returned me followed error:

Type 'Optional<Wrapped>' does not conform to protocol 'OptionalProtocol'
Candidate can not infer 'Wrapped' = 'Wrapped' because 'Wrapped' is not a nominal type and so can't conform to 'OptionalWrapped' (Swift.Optional.some)
Candidate can not infer 'Wrapped' = 'Wrapped' because 'Wrapped' is not a nominal type and so can't conform to 'OptionalWrapped'

Is it a bug?
If not, could you advise how to solve this problem to make it working back for Swift 6.2?

Could you include some code that triggers the error? I do not see the problematic source here.

It is in my first post:

/// An abstraction for `Optional<Wrapped>`.
public protocol OptionalProtocol: ExpressibleByNilLiteral {

    associatedtype Wrapped

    static var none: Self { get }
    static func some(_ value: Wrapped) -> Self

    /// Unwraps optional.
    /// - Returns: Unwrapped value.
    func unwrapped() throws -> Wrapped
}

and

extension Optional: OptionalProtocol {

    /// Unwraps optional and throws error when `nil` encountered.
    /// - Returns: Unwrapped value.
    public func unwrapped() throws -> Wrapped {
        switch self {
        case .none: throw Self.Error.nullValue
        case .some(let wrapped): return wrapped
        }
    }

    public enum Error: Swift.Error {
        case nullValue
    }
}

Here is problematic line from OptionalProtocol:

static func some(_ value: Wrapped) -> Self

The error appears with Xcode 26 beta 1 and beta 2.

I should have been more clear. I was interested in seeing the client code that uses optional, but it may not be necessary.

  1. Is it all uses of unwrapped? or just specific ones?

  2. Since you are extending Optional, do you have to include some & none & Wrapped in the protocol? Redefining elements of as existing type is not a common thing to do. I am not sure if your goal is to just get things working or get to the root cause of the issue, but you might want to try something like the following to see if it compiles :

// No protocols are defined
extension Optional {
	func unwrap() throws -> Wrapped {
		switch self {
		case .none: throw Self.Error.nullValue
		case .some(let wrapped): return wrapped
		}
	}

	public enum Error: Swift.Error {
		case nullValue
	}
}

You may have a good reason to create a protocol with some & none & Wrapped but retroactively conforming Optional to it may not be necessary. Defining the smallest protocol required seems like a good practice in general. I am not saying that it is not a bug or at least should produce better diagnostic output.

I don't know what's going on here; a simplified version to trigger the bug is:

public protocol OptionalProtocol {
    associatedtype Wrapped
    static func some(_ value: Wrapped) -> Self
}

extension Optional: OptionalProtocol {}
DEVELOPER_DIR=/Applications/Xcode-26.0.0-Beta.2.app xcrun swiftc -swift-version 6 Optional62.swift
<unknown>:0: error: lifetime-dependent variable '$implicit_value' escapes its scope

but this formulation compiles:

public protocol OptionalProtocol {
    associatedtype Wrapped
    init(_ value: Wrapped)
}

public extension OptionalProtocol {
    static func some(_ value: Wrapped) -> Self {
        Self(value)
    }
}

extension Optional: OptionalProtocol {}
2 Likes

It's possible we might be missing more early returns here:

@Andrew_Trick might know what's going on… if there are any known issues left in LifetimeDependenceDiagnostics.swift.

I hit this, too. I believe this was the resolution: Add lifetime dependencies on function types representing ~Escapable enum elements with ~Escapable payloads by meg-gupta · Pull Request #82354 · swiftlang/swift · GitHub

4 Likes