Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apparent compiler bug relating to Optional witnessing failable initializer requirement #78409

Open
jeremyabannister opened this issue Jan 2, 2025 · 2 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler itself conformances Feature → protocol: protocol conformances init Feature → declarations: Initializers Optional Area → standard library: The `Optional` type SILGen Area → compiler: The SIL generation stage swift 6.0 unexpected behavior Bug: Unexpected behavior or incorrect output

Comments

@jeremyabannister
Copy link

Description

I think this must be a bug. The following test passes if the Optional initializer is declared as a failable initializer, but fails if the ? is removed from the Optional initializer.

The Test

@Test
func foo() {
    #expect(
        Demo<Optional<Int>>.test()
    )
}
struct Demo<T: Foo> {
    static func test() -> Bool {
        if let a = T.init() {
            return true
        }
        return false
    }
}
protocol Foo {
    init?()
}

Passes If Optional Conforms Like This:

extension Optional: Foo {
    init?() {
        self = Self.none
    }
}

Fails If Optional Conforms Like This:

extension Optional: Foo {
    init() {
        self = Self.none
    }
}

Original Swift Forums Post: https://forums.swift.org/t/apparent-compiler-bug-relating-to-optional-witnessing-failable-initializer-requirement/76759

Reproduction

@Test
func foo() {
    #expect(
        Demo<Optional<Int>>.test()
    )
}
struct Demo<T: Foo> {
    static func test() -> Bool {
        if let a = T.init() {
            return true
        }
        return false
    }
}
protocol Foo {
    init?()
}
extension Optional: Foo {
    init() {
        self = Self.none
    }
}

Expected behavior

I expected that the unwrapping if let a = T.init() { } would succeed since in this case T == Optional<Int> and Optional unconditionally succeeds in initializing itself to .none.

Environment

Swift 6

Additional information

No response

@jeremyabannister jeremyabannister added bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels labels Jan 2, 2025
@AnthonyLatsis AnthonyLatsis added compiler The Swift compiler itself unexpected behavior Bug: Unexpected behavior or incorrect output init Feature → declarations: Initializers swift 6.0 Optional Area → standard library: The `Optional` type and removed triage needed This issue needs more specific labels labels Jan 6, 2025
@AnthonyLatsis
Copy link
Collaborator

This simpler example might help. A failable initializer returns an optional of the parent type — a double optional in this case. Since I am not returning nil, neither is the resulting Int?? value nil:

extension Optional {
  init?(failable: Void) {
    self = Self.none
  }
  init(nonfailable: Void) {
    self = Self.none
  }
}

do {
  let _ = Int?.init(failable: ())    // == Int??.some(Int?.none)
  let _ = Int?.init(nonfailable: ()) // == Int?.none
}

@AnthonyLatsis AnthonyLatsis added SILGen Area → compiler: The SIL generation stage conformances Feature → protocol: protocol conformances labels Jan 6, 2025
@AnthonyLatsis
Copy link
Collaborator

Sorry, I was not paying enough attention. I see now.

@AnthonyLatsis AnthonyLatsis self-assigned this Jan 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler itself conformances Feature → protocol: protocol conformances init Feature → declarations: Initializers Optional Area → standard library: The `Optional` type SILGen Area → compiler: The SIL generation stage swift 6.0 unexpected behavior Bug: Unexpected behavior or incorrect output
Projects
None yet
Development

No branches or pull requests

2 participants