<div dir="ltr">Here&#39;s a simplified section of code I&#39;m writing for mapping some data from over the wire<div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><br></div><div>public protocol Transform {</div><div>    // a bunch of stuff</div><div>}</div><div><br></div><div>public protocol Key {</div><div>    // a bunch of stuff</div><div>}</div><div><br></div><div>extension String: Key { /* conforming stuff */ }</div><div><br></div><div>public protocol JSONType { }</div><div>extension Int: JSONType { }</div><div><br></div><div>public enum Bind&lt;T&gt;: Key {</div><div>    case transform(Key, T)</div><div>    // a few more cases, every case must have a Key, we forward all of Key&#39;s methods through each case.</div><div>}</div><div><br></div><div>public func map&lt;T: JSONType&gt;(field: inout T, binding: Key) {</div><div>    print(field)</div><div>}</div><div><br></div><div>public func map&lt;T, U: Transform&gt;(field: inout T, binding: Bind&lt;U&gt;) {</div><div>    print(field)</div><div>}</div><div><br></div><div>class SpecialTransform: Transform { }</div><div><br></div><div>var s = Int()</div><div>// Ambiguity here.</div><div>map(field: &amp;s, binding: Bind.transform(&quot;data.stuff&quot;, SpecialTransform()))</div></blockquote></div><div><br><div>Probably would be better to make `Bind` not conform to `Key`, would just require a bunch of refactoring in places where I&#39;ve used the two interchangeably. However, one of the benefits of having `Bind: Key` is that it enforces that every additional case has a `Key` which will always be true for this data structure.</div></div><div><br></div><div><div>I was thinking the first `map` would change  to</div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div>public func map&lt;T: JSONType, K: Key&gt;(field: inout T, binding: K)</div></div></blockquote><div><br></div><div>But to have `K != Bind&lt;Any&gt;`, Bind&lt;Any&gt; would have to be the super type of all other Bind&lt;T&gt;s which currently isn&#39;t true anyway so this is kind of dead on arrival.</div><div><br></div><div><div>Interestingly though, when I change the signature to </div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>public func map&lt;T: JSONType, K: Key&gt;(field: inout T, binding: K)</div></blockquote><div><br></div><div>Instead of &quot;Ambiguous use of...&quot;, the program compiles and calls this method instead of the overload with Bind&lt;U&gt;. Not only is this not the function I want called, but this seems like inconsistent behavior with the type checker (compiling vs throwing an &quot;Ambiguous use of...&quot; error).</div><div>Should I report a bug here or am I missing something?</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Feb 28, 2017 at 9:35 AM, Matthew Johnson <span dir="ltr">&lt;<a href="mailto:matthew@anandabits.com" target="_blank">matthew@anandabits.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><span class=""><blockquote type="cite"><div>On Feb 28, 2017, at 11:33 AM, Joe Groff &lt;<a href="mailto:jgroff@apple.com" target="_blank">jgroff@apple.com</a>&gt; wrote:</div><br class="m_-3967364951621681103Apple-interchange-newline"><div><blockquote type="cite" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br class="m_-3967364951621681103Apple-interchange-newline">On Feb 28, 2017, at 9:23 AM, Matthew Johnson &lt;<a href="mailto:matthew@anandabits.com" target="_blank">matthew@anandabits.com</a>&gt; wrote:<br><br><br><blockquote type="cite">On Feb 28, 2017, at 11:04 AM, Joe Groff via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br><br><br><blockquote type="cite">On Feb 27, 2017, at 4:34 PM, Rex Fenley via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br><br>I often find myself running into situations where I&#39;ll receive &quot;Ambiguous use of...&quot; for overloaded functions or operators. In every case these situations would be easily solved if I could specify &quot;Generic != CertainType&quot; in the where clause of one of the overloads so I can disambiguate the cases. Could this be added to language?<br></blockquote><br>Do you have a concrete example where you need this? It&#39;d be good to know whether the types are ambiguous due to type checker bugs, or whether there&#39;s a principle by which they could be naturally ordered. Instead of overloading, can you do the type test via `if !(x is CertainType)` within a single implementation?<br></blockquote><br>The best use case I can think of is if we had enum cases where the associated value is a subtype of the enum:<br><br>enum Result&lt;T, E&gt; where E: Error, T != E {<br>  case some(T) -&gt; T<br>  case error(E) -&gt; E<br>}<br></blockquote><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important">I don&#39;t think that&#39;s a good design for that type. I can see the desire for a subtype relationship between T and Result&lt;T, E&gt;, but no good reason for the error to also be a subtype. That != constraint would have to be propagated through anything using `Result&lt;T, E&gt;` as well.</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"></div></blockquote><div><br></div></span><div>Ok, just change it to a fully generic Either type then.  I’m not arguing for or against this constraint, just pointing out a use case that is enabled by it.  It’s reasonable to argue that we don’t want to support this use case.</div><br><blockquote type="cite"><div><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important">-Joe</span></div></blockquote></div><br></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><span><p dir="ltr" style="line-height:1.15;margin-top:0pt;margin-bottom:0pt"><span style="font-size:16px;font-family:Arial;background-color:transparent;font-style:italic;vertical-align:baseline;white-space:pre-wrap">Rex Fenley</span><span style="font-size:16px;font-family:Arial;background-color:transparent;vertical-align:baseline;white-space:pre-wrap">  </span><span style="font-size:11px;font-family:Arial;color:rgb(153,153,153);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">|</span><span style="line-height:1.15;font-family:Arial;color:rgb(153,153,153);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">  </span><span style="font-size:11px;font-family:Arial;color:rgb(153,153,153);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">IOS DEVELOPER</span><br></p></span><span><br><p dir="ltr" style="line-height:1.15;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11px;font-family:Arial;color:rgb(153,153,153);vertical-align:baseline;white-space:pre-wrap;background-color:transparent"><img src="https://lh5.googleusercontent.com/xMgzw3JkFL3DLkdwyq0WxJzKs_XP57gVVCaBMvgi1FKCjSeue0xdx3JZeCWBlxN4KRHhHOfdvJbc1N-AjTwXcKIq4cjJg9H7iaFpQ8WbO4N3c9Y5dzi19cPOs_owPquuqw" width="250px;" height="53px;" style="border:none"></span></p><p dir="ltr" style="line-height:1.15;margin-top:0pt;margin-bottom:0pt"><a href="https://www.remind.com/" style="text-decoration:none" target="_blank"><span style="font-size:11px;font-family:Arial;color:rgb(17,85,204);font-weight:bold;text-decoration:underline;vertical-align:baseline;white-space:pre-wrap;background-color:transparent">Remind.com</span></a><span style="font-family:Arial;vertical-align:baseline;white-space:pre-wrap;background-color:transparent"> </span><span style="font-size:11px;font-family:Arial;vertical-align:baseline;white-space:pre-wrap;background-color:transparent">|  </span><a href="http://blog.remind.com/" style="text-decoration:none" target="_blank"><span style="font-size:11px;font-family:Arial;color:rgb(17,85,204);text-decoration:underline;vertical-align:baseline;white-space:pre-wrap;background-color:transparent">BLOG</span></a><span style="font-size:11px;font-family:Arial;vertical-align:baseline;white-space:pre-wrap;background-color:transparent">  |  </span><a href="https://twitter.com/remindhq" style="text-decoration:none" target="_blank"><span style="font-size:11px;font-family:Arial;color:rgb(17,85,204);text-decoration:underline;vertical-align:baseline;white-space:pre-wrap;background-color:transparent">FOLLOW US</span></a><span style="font-size:11px;font-family:Arial;vertical-align:baseline;white-space:pre-wrap;background-color:transparent">  | </span><span style="font-family:Arial;vertical-align:baseline;white-space:pre-wrap;background-color:transparent"> </span><span style="text-decoration:underline;font-size:11px;font-family:Arial;color:rgb(17,85,204);vertical-align:baseline;white-space:pre-wrap;background-color:transparent"><a href="https://www.facebook.com/remindhq" style="text-decoration:none" target="_blank">LIKE US</a></span></p></span></div></div>
</div>