Why 'any' needed when associated type known

I'm happy that Swift has introduced the primary associated type for protocols.
But I feel like they need some boost/improvement.
Cause currently, it's super confusing why we can't use protocols with a known primary associated type the same way as we use non-generic protocols.

We can currently use for regular protocols:

protocol RegularProtocol {}
var listOfRegularProtocol = [RegularProtocol]()

But when we have:

protocol SomeGenericProtocol<T> {
	associatedtype T
	var value: T { get }
}

typealias IntValueProtocol = SomeGenericProtocol<Int>
// ❎ Use of 'IntValueProtocol' (aka 'SomeGenericProtocol<Int>') as a type must be written 'any IntValueProtocol' (aka 'any SomeGenericProtocol<Int>')
let intValueProtocols = [IntValueProtocol]()
// ✅ needs any keyword
let intValueProtocolsSuccess = [any IntValueProtocol]()

But we know that type T can't be anything else than Int.
It will be equivalent to:

protocol SomeProtocol {
	var value: Int { get }
}
let someProtocols = [SomeProtocol]()

This works but if the same declaration would be SomeProtocol: SomeGenericProtocol<Int> then again we need any for usage.

And the same for:

protocol IKnowThatAssociatedTypeIsInt: SomeGenericProtocol where T == Int {}
let intValueProtocols2 = [any IKnowThatAssociatedTypeIsInt]()

Is there any change that we get rid of needed any keyword where we have declared the associated type?

1 Like

Hi @mrtsamma, this works right now for source compatibility reasons, but it will not work in Swift 6. In other words, Swift will always require the any keyword soon.

8 Likes

Ok. That explains it. Thanks

I'm not sure, but I think it was at least discussed to actually do the opposite and at some point in the future always require any if you are using a protocol as a type.

Conceptually you still do not know what concrete type will be stored in e.g. the intValueProtocols variable in your example. Just that it adopts IntValueProtocol.

Since before we had any at all protocols without associated types could simply be used as a type to denote storage we now have a kind of "legacy hole". I don't know which direction this will go, but there's a point to be made to say "we better always explicitly denote when we want a variable that can hold any type that adopts a protocol", regardless of whether that protocol has associated types or not.

edit:
I guess @xwu clarified this then. :) Thanks! Personally I am all for requiring any in the future.

1 Like