<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Yeah, this is an unfortunate wart. Right now unqualified lookup starts at the innermost scope and stops when it finds a candidate which matches the name being looked up. Overload sets are only formed if there are multiple candidates inside the same scope, not in different scopes.<div class=""><br class=""></div><div class="">It would be nice to fix this but note that it might have a compile-time performance impact, because now we will be looking up names in more scopes. In particular, this means almost every name lookup will have to look at all imported modules.</div><div class=""><br class=""></div><div class="">If this can be implemented in a clever way without impacting compile time, I’ll be all for this change.</div><div class=""><br class=""></div><div class="">However, note that the most common way in which people hit this is with type(of:) vs a local name named type — I think this can be solved without fundamentally changing unqualified lookup, by having unqualified lookup look at the DeclName rather than an Identifier. So if you have</div><div class=""><br class=""></div><div class="">var type = …</div><div class=""><br class=""></div><div class="">type(of: foo)</div><div class=""><br class=""></div><div class="">We would not consider the ‘var type’ at all, since it doesn’t match the DeclName type(of:). This might also address min vs Collection.min if we consider the number of arguments when performing the lookup too.</div><div class=""><br class=""></div><div class=""><div class="">Either way I think an evolution proposal is a good idea, this has source compatibility impact since it can introduce ambiguity at call sites that were formerly unambiguous. But we should be careful not to impact compile time.</div></div><div class=""><br class=""></div><div class="">Slava<br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Nov 12, 2017, at 5:12 PM, Nevin Brackett-Rozinsky via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">I brought this up on Swift Dev and was told to check on Swift Evolution to see if a proposal is needed.<div class=""><br class=""></div><div class="">Currently, the following code produces a compiler error:</div><div class=""><br class=""></div><div class=""><font face="monospace, monospace" class="">func foo(_ x: Int, _ y: Int) -&gt; Int {</font></div><div class=""><font face="monospace, monospace" class="">&nbsp; return x + y</font></div><div class=""><font face="monospace, monospace" class="">}</font></div><div class=""><font face="monospace, monospace" class=""><br class=""></font></div><div class=""><font face="monospace, monospace" class="">extension Int {</font></div><div class=""><font face="monospace, monospace" class="">&nbsp; func foo() -&gt; Int {</font></div><div class=""><font face="monospace, monospace" class="">&nbsp; &nbsp; return foo(self, self)&nbsp; &nbsp; // Error here</font></div><div class=""><font face="monospace, monospace" class="">&nbsp; }</font></div><div class=""><font face="monospace, monospace" class="">}</font></div><div class=""><br class=""></div><div class="">Notice that the two functions named “foo” have entirely different signatures. The global function takes 2 arguments, while the member function takes 0 (or 1, if referenced as “Int.foo”).</div><div class=""><br class=""></div><div class="">There is exactly one function “foo” which takes 2 arguments, so a call to “foo” with 2 arguments, like the one shown, should be unambiguous. However, instead of calling the function with matching signature, there is instead a compiler error.</div><div class=""><br class=""></div><div class="">This is already documented as <a href="https://bugs.swift.org/browse/SR-2450" class="">SR–2450</a>, with an example from the standard library (global 2-argument “min” vs. 0-argument “Collection.min”).</div><div class=""><br class=""></div><div class="">It appears that in any situation where a global function and a member function share the same base name, but only the global function’s signature matches the call site, the result is a compiler error.</div><div class=""><br class=""></div><div class="">I suggest that, when there is exactly one function available with the proper name and signature, instead of a compiler error the matching&nbsp;function should be called.</div><div class=""><br class=""></div><div class="">Do we need a Swift Evolution proposal for this change?</div><div class=""><br class=""></div><div class="">Nevin</div></div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></div></body></html>