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

Failure to implicitly open existential on initialization through factory method #59851

Open
eito opened this issue Jul 1, 2022 · 1 comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior.

Comments

@eito
Copy link

eito commented Jul 1, 2022

Describe the bug
Per the thread here: SE-0352 allows the implicit opening of existentials only when the generic type occurs exactly once in the function signature. In the sample code from the thread's first post, the init of S is implicitly using the generic type twice.

protocol P {
  associatedtype A
  func getA() -> A
}

struct S<T: P> {
    var s: T
}

func testOpenSimple(p: any P) {
  let _ = S(s: p) // **error**, Type 'any P' cannot conform to 'P'
}

An alternative approach was proposed here by @jckarter that involves a static factory method that returns the S as a protocol existential or opaque return type.

Applying this approach still yields the same error Type 'any P' cannot conform to 'P' and @jckarter thought it seemed like a bug.

To Reproduce

  1. Attempt to run the following Swift code in a Playground with Xcode 14 beta 2 (Swift 5.7)
protocol P {
  associatedtype A
  func getA() -> A
}

protocol Q {}
struct S<T: P>: Q {
  var s: T

  static func make(s: T) -> some Q { return S(s: s) }
}

func testOpenSimple(p: any P) {
  let q = S.make(s: p) // q has type `any Q`
}

Expected behavior
Should build successfully and allow the initialization of S through the factory method resulting in an instance of any Q living in q

Screenshots
image

Environment (please complete the following information):

  • OS: [e.g. macOS 11.0] macOS 12.4/iOS 16.0
  • Xcode Version/Tag/Branch: 14 beta 2

Additional context

@eito eito added the bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. label Jul 1, 2022
@Kyle-Ye
Copy link
Contributor

Kyle-Ye commented Jul 2, 2022

A temporary workaround

func testOpenSimple(p: any P) {
    // Error
    //  let q = S.make(s: p) // q has type `any Q` 

    func bridge2<T: P>(_ s: T) -> some Q {
        S.make(s: s)
    }
    
    let q = bridge2(p)
}

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.
Projects
None yet
Development

No branches or pull requests

2 participants