"ambiguous for type lookup" problem

I need help with understanding protocols with associated types.


Why this code doesn't compile:


protocol A {
  typealias AssociatedType
}

extension A where Self: MyClass {
  func f(x: AssociatedType) { //'AssociatedType' is ambiguous for type lookup...
    // do stuff
  }
}

class MyClass: A {
  typealias AssociatedType = Int
}


but it works when class is replaced with subclass


protocol A {
  typealias AssociatedType
}

extension A where Self: MyClass {
  func f(x: AssociatedType) {
    // do stuff
  }
}

class MySubclass: MyClass, A {
  typealias AssociatedType = Int
}

Accepted Reply

An interesting example.


In your first code, two AssociatedTypes are available in the extension context. A.AssociatedType and MyClass.AssociatedType .

(`A.AssociatedType` is not a valid representation outside the protocol A, but it's another issue.)

And, it seems Swift cannot utilize the fact that two AssociatedTypes are the same. So complaining about they are `ambiguous`.


In your second code, you are omitting the definition of MyClass, so assuming:

class MyClass {}

In this case, in the extension context, AssociatedType can only represent A.AssociatedType, so Swift compiler does not complain.


With modifying your code by specifying which AssociatedType you mean, you can make Swift silent:

extension A where Self: MyClass {
    func f(x: MyClass.AssociatedType) {
        // do stuff
    }
}

Replies

An interesting example.


In your first code, two AssociatedTypes are available in the extension context. A.AssociatedType and MyClass.AssociatedType .

(`A.AssociatedType` is not a valid representation outside the protocol A, but it's another issue.)

And, it seems Swift cannot utilize the fact that two AssociatedTypes are the same. So complaining about they are `ambiguous`.


In your second code, you are omitting the definition of MyClass, so assuming:

class MyClass {}

In this case, in the extension context, AssociatedType can only represent A.AssociatedType, so Swift compiler does not complain.


With modifying your code by specifying which AssociatedType you mean, you can make Swift silent:

extension A where Self: MyClass {
    func f(x: MyClass.AssociatedType) {
        // do stuff
    }
}

Now I understand, thanks 🙂