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

Extensions to protocol typealias types compile but can't be accessed #61450

Closed
daniel-hall opened this issue Oct 5, 2022 · 1 comment
Closed
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler itself type checker Area → compiler: Semantic analysis

Comments

@daniel-hall
Copy link

daniel-hall commented Oct 5, 2022

Describe the bug

If I declare a typealias for a concrete type in a protocol, e.g.

struct A { }

protocol P {
  typealias Element = A
}

and then I write an extension based on that typealias on a conforming type, e.g.:

struct Conforming: P { }

extension Conforming.Element { // This should be identical to `extension A`
  var success: Bool { true }
}

The compiler allows it. But trying to access the extension property will fail:

print(Conforming.Element().success) //Compiler error:  "Value of type 'Conforming.Element' (aka 'A') has no member 'success'"

If I declare the extension directly on the type (not through the typealias), e.g.

extension A {
  var success: Bool { true }
}

Then the same print statement (accessing type A through the protocol typealias) will succeed

Declaring the typealias directly on the type allows the extension through the typealias to work:

struct Conforming {
  typealias Element = A
}

extension Conforming.Element { 
  var success: Bool { true }
}

print(Conforming.Element().success) //  "true"

It only seems to fail on the requirement of writing an extension that refers to a typealias declared by a protocol.

Environment (please fill out the following information)

  • OS: macOS 12.6
  • Xcode Version/Tag/Branch: Version 14.0 (14A309)

Additional context

Ultimately what I want to accomplish is something like this (just a convenience really)

protocol SettingsProvider { 
  typealias SettingsConfiguration = Configuration<Self>
}

struct Configuration<T> { }

struct ConcreteType: SettingsProvider { }

// I want to be able to do this
extension ConcreteType.Settings {
  var someProperty: String
}

// Instead of this equivalent that seems much less intuitive to me
extension Configuration<ConcreteType> {
  var someProperty: String
}

Swift Forums thread here

@daniel-hall daniel-hall added the bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. label Oct 5, 2022
@theblixguy theblixguy added the type checker Area → compiler: Semantic analysis label Oct 5, 2022
@slavapestov
Copy link
Contributor

This is now diagnosed on main:

q.swift:9:1: error: extension of type 'Conforming.Element' (aka 'A') must be declared as an extension of 'A'
extension Conforming.Element { // This should be identical to `extension A`
^         ~~~~~~~~~~~~~~~~~~
q.swift:9:1: note: did you mean to extend 'A' instead?
extension Conforming.Element { // This should be identical to `extension A`
^         ~~~~~~~~~~~~~~~~~~
          A

Fix was #60364

@AnthonyLatsis AnthonyLatsis added the compiler The Swift compiler itself label Dec 13, 2022
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 type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

4 participants