> On Sep 26, 2016, at 5:18 PM, Douglas Gregor via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> Conditional conformances
> 
>  
> <https://github.com/DougGregor/swift-evolution/tree/conditional-conformances#disallow-overlapping-conformances>Disallow
>  overlapping conformances
> 
> With conditional conformances, it is possible to express that a given generic 
> type can conform to the same protocol in two different ways, depending on the 
> capabilities of its type arguments. For example:
> 
> …
> 
> Note that, for an arbitrary type T, there are four potential answers to the 
> question of whether SomeWrapper<T> conforms to Equatable:
> 
> No, it does not conform because T is neither Equatable nor HasIdentity.
> Yes, it conforms via the first extension of SomeWrapper because T conforms to 
> Equatable.
> Yes, it conforms via the second extension of SomeWrapper because T conforms 
> to HasIdentity.
> Ambiguity, because T conforms to both Equatable and HasIdentity.
> It is due to the possibility of #4 occurring that we refer to the two 
> conditional conformances in the example as overlapping. There are designs 
> that would allow one to address the ambiguity
> 
> …
> 
> For these reasons, this proposal bans overlapping conformances entirely. 

What other designs were considered and rejected? It seems like some kind of 
escape hatch would be preferred if you happen to get into this situation, 
though you make some really good points about the pitfalls.

Just to clarify when you say “bans” do you mean if Wrapped: Equatable & 
HasIdentity then SomeWrapper is not Equatable, or do you mean you get a compile 
error because there are two constrained conformances SomeWrapper: Equatable? 
What would be the problem with allowing multiple conformances to Equatable so 
long as the constraints are disjoint or the concrete type only adopts one of 
the available protocols?

>  
> <https://github.com/DougGregor/swift-evolution/tree/conditional-conformances#implied-conditional-conformances>Implied
>  conditional conformances
> 
> Stating conformance to a protocol implicitly states conformances to any of 
> the protocols that it inherits. This is the case in Swift today, although 
> most developers likely don't realize the rules it follows. For example:
> 
> protocol P { }
> protocol Q : P { }
> protocol R : P { }
> 
> struct X1 { }
> struct X2 { }
> struct X3 { }
> 
> extension X1: Q { }  // implies conformance to P
> 
> extension X2: Q { }  // would imply conformance to P, but...
> extension X2: P { }  // explicitly-stated conformance to P "wins"
> 
> extension X3: Q { }  // implies conformance to P
> extension X3: R { }  // also implies conformance to P
>                      // one will "win"; which is unspecified
On X2 you’re declaring a redundant conformance to P but any protocol extensions 
will prefer Q and the compiler won’t let you redefine any members so you’ll 
have an incomplete conformance. Any explicit conformances (on the type or in 
extensions) are preferred over the defaults from the protocol extension, but 
that’s not new. I must be missing something, how would this be visible in Swift 
3?

On X3, multiple implementations in protocol extensions are errors today and the 
resolution is to provide an explicit implementation on X3.




> With conditional conformances, the question of which extension "wins" the 
> implied conformance begins to matter, because the extensions might have 
> different constraints on them. For example:
> 
> struct X4<T> { }
> 
> extension X4: Q where T: Q { }  // implies conformance to P
> extension X4: R where T: R { }  // error: implies overlapping conformance to P
> Both of these constrained extensions imply a conformance to P, but the actual 
> P implied conformances to P are overlapping and, therefore, result in an 
> error.
> 
If the related P conformance were inherited from conformance to Q or R then the 
rules would (IMHO) make more sense. Wouldn’t the extra rule you need simply be 
that either Q or R must provide a complete conformance to P (no mix-n-match)? 

If T implements Q & P why not just ignore T: P which means the X4: R extension 
is no longer relevant. 

It seems like the tricky case is T: P and the same question applies - why not 
just ignore the extensions (X4<T> in that scenario doesn’t implement Q, R, or 
P). 


Not allowing ambiguity seems like it solves the “which one” problem and 
requiring an extension to provide the entire implementation (no mix-n-match) 
cuts down on the cleverness problem.




> However, in cases where there is a reasonable ordering between the two 
> constrained extensions (i.e., one is more specialized than the other), the 
> less specialized constrained extension should "win" the implied conformance. 
> Continuing the example from above:
> 
> protocol S: R { }
> 
> struct X5<T> { }
> 
> extension X5: R where T: R { }  // "wins" implied conformance to P, because
> extension X5: S where T: S { }  // the extension where "T: S" is more 
> specialized
>                                 // than the one where "T: R"
> Thus, the rule for placing implied conformances is to pick the least 
> specialized extension that implies the conformance. If there is more than one 
> such extension, then either:
> 
> All such extensions are not constrained extensions (i.e., they have no 
> requirements beyond what the type requires), in which case Swift can continue 
> to choose arbitrarily among the extensions, or
> All such extensions are constrained extensions, in which case the program is 
> ill-formed due to the ambiguity. The developer can explicitly specify 
> conformance to the protocol to disambiguate. 
What is the rationale for picking the least specialized extension? That’s not 
what I would naively expect to happen. If T: R & S then I would expect the more 
specialized S:R implementation to be preferred, and the explicit R 
implementation to kick in when T: R. 



(Some of these may just be naive questions resulting from my misunderstanding)

Russ





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

Reply via email to