-1 — this adds a new syntax with little gain, and potentially a lot of 
additional complexity.

> On Aug 16, 2016, at 2:49 PM, Charles Srstka via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> Unfortunately, when this has come up on the list in the past, it has been 
> mentioned that there are some cases where an existential of a protocol does 
> not conform to the protocol itself, so it is impossible to make : always 
> match items that are typed to the protocol.

Indeed, the best solution IMHO would be to implement self-conforming protocols, 
so that what you’re describing can be expressed without any additional syntax.

The condition for a protocol to be able to conform to itself is the following:

- it must not have any associated type requirements, or contravariant Self in 
requirement signatures; eg, this rules out the following:

  protocol P { func foo(s: Self) }

- it must not have any static method or initializer requirements

With these conditions met, it would be possible to allow a generic parameter ’T 
: P’ to bind to a concrete type ’P’.

Note that the type checker work required for this is not very difficult. 
Indeed, we already allow @objc protocols that don’t have static requirements to 
self-conform. The real issue is the runtime representation gets tricky, if you 
want to allow a generic parameter to contain both a concrete type conforming to 
P, and an existential of P. Basically a generic parameter is passed as three 
values behind the scenes, the actual value, type metadata for the concrete 
type, and a witness table for the conformance. To allow the parameter to be 
bound to an existential type we would need to pass in a special witness table 
that unpacks the existential and calls the witness table contained in the 
existential.

It’s even worse if the protocol that self-conforms is a class-bound protocol. A 
generic parameter conforming to a class-bound protocol is passed as a reference 
counted pointer and witness table. Unfortunately, a class-bound existential is 
*not* a reference counted pointer — it has the witness table ‘inside’ the value.

Probably my explanation isn’t great, but really what’s bothering you here isn’t 
a language limitation, it’s an implementation limitation — once we figure out 
how to represent protocol existentials efficiently in a way allowing them to 
self-conform, we should be able to address these use-cases without new syntax.

Cheers,

Slava

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to