<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body><div>Whether the protocol inherits from another protocols does not matter. As long as the protocol requirements include associated types, it would not be possible to be used as existentials (for now).<br></div>
<div><br></div>
<div>Moreover, even if you use the "subprotocols" inside a generic environment that constrains `A`, it does not change how the symbol `B` and `C` mean inside that context. They are still unbound protocols.<br></div>
<div><br></div>
<div>The feature you called for is generalized existentials. It is on the Generic Manifesto and had a few long discussion threads on the list before. Apparently, it is out of scope for Swift 4, and whether it is in scope of Swift 5 remains to be seen.<br></div>
<div><br></div>
<div>By the way, for your code snippet, apparently you may simply add "doSomething" overloads for `P: B` and `P: C`. The compiler will pick the most specific variant for you at compile time. Deferring to runtime with existentials is not necessarily the only option.<br></div>
<div><br></div>
<div>On Sun, Jun 25, 2017, at 01:50 AM, Benjamin Spratling via swift-evolution wrote:<br></div>
<blockquote type="cite"><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);">I’m running into trouble using protocols as types when they have an associated type. I understand the restriction of using a protocol with an associated type only as a generic constraint, since our down-casting syntax has no way of checking the associated types. However, if I’m considering whether an instance conforms to a sub protocol, which introduces no additional associated types itself, when the instance is already known to conform to the super-protocol which introduces the associated type, I believe such behavior is well-defined, and should be supported. So, I’m asking for help to put together a proposal to get this added.<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);min-height:14px;"><br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);">Here’s an example:<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);">3 protocols, one base Protocol which declares an associated type.<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);">And 2 sub-protocols.<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);min-height:14px;"><br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);">protocol A {<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);"><span style="white-space:pre;"></span>associatedType V<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);">}<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);min-height:14px;"><br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);">protocol B : A {<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);"><span style="white-space:pre;"></span>func someFunction<V>(V?)->String<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);">}<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);min-height:14px;"><br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);">protocol C : B {<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);"><span style="white-space:pre;"></span>func someOtherFunction<V>()->V?<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);">}<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);min-height:14px;"><br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);">Note that the sub protocols do not add additional associated types.<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);min-height:14px;"><br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);">When I want to use these protocols, using the base protocol as a generic constraint works fine.<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);min-height:14px;"><br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);">class M {<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);"><span style="white-space:pre;"></span>func doSomething<P, V>(a:P, completion:@escaping(V?)->()) where P : A, V==P.V {<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);"><span style="white-space:pre;"></span>if let c = a as? C {<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);"><span style="white-space:pre;"></span>c.someOtherFunction(…)<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);"><span style="white-space:pre;"></span>… more code<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);"><span style="white-space:pre;"></span>} else if let b = a as? B {<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);"><span style="white-space:pre;"></span>b.someFunction(…)<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);"><span style="white-space:pre;"></span>… more code<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);"><span style="white-space:pre;"></span>}<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);"><span style="white-space:pre;"></span>}<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);">}<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);min-height:14px;"><br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);">However, when I try to check whether the instance conforms to either of the sub-protocols, I get an error, saying protocols with associated types can only be used as generic constraints.<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);min-height:14px;"><br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;font-family:'Helvetica Neue';color:rgb(69, 69, 69);">I believe that in this case, since the sub-protocols do not add any additional associated types, this code should be well-defined, and compilable.<br></div>
<div><br></div>
<div><u>_______________________________________________</u><br></div>
<div>swift-evolution mailing list<br></div>
<div><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br></div>
<div><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></div>
</blockquote><div><br></div>
</body>
</html>