<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Sep 26, 2017, at 18:02, Robert Widmann via swift-dev <<a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div 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; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class=""><br class="Apple-interchange-newline">On Sep 25, 2017, at 10:01 AM, Nevin Brackett-Rozinsky <<a href="mailto:nevin.brackettrozinsky@gmail.com" class="">nevin.brackettrozinsky@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class=""><font face="monospace, monospace" class="">func triple(_ x: Int) -> Int {</font></div><div class=""><font face="monospace, monospace" class=""> return 3 * x</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=""> func triple() -> Int {</font></div><div class=""><font face="monospace, monospace" class=""> return triple(self) // Error here</font></div><div class=""><font face="monospace, monospace" class=""> }</font></div><div class=""><font face="monospace, monospace" class="">}</font></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">The error reads:</div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><font face="monospace, monospace" class="">Playground execution failed:<br class="">error: Test.playground:5:16: error: use of 'triple' refers to instance method 'triple()' rather than global function 'triple' in module '__lldb_expr_52'<br class=""> return triple(self) // Error here<br class=""> ^<br class="">Test.playground:5:16: note: use '__lldb_expr_52.' to reference the global function in module '__lldb_expr_52'<br class=""> return triple(self) // Error here<br class=""> ^<br class=""> __lldb_expr_52.</font></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Notice where the error says, “use of 'triple' refers to instance method 'triple()' rather than global function 'triple'”.</div><div class=""><br class=""></div><div class="">Notice further that the instance method takes 0 arguments. In particular, “self.triple()” is a valid way to call it, and “self.triple(self)” is not.</div><div class=""><br class=""></div><div class="">It is true that the instance method could be called as a type method with 1 argument, “Int.triple(self)”. However, “triple(self)” is not a valid way to call the type method, which we can demonstrate by removing the global function entirely:</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div class=""><font face="monospace, monospace" class="">extension Int {</font></div><div class=""><font face="monospace, monospace" class=""> func triple() -> Int {</font></div><div class=""><font face="monospace, monospace" class=""> return triple(self) // Error here</font></div><div class=""><font face="monospace, monospace" class=""> }</font></div><div class=""><font face="monospace, monospace" class="">}</font></div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">This time the error reads:</div><div class=""><br class=""></div><div class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><font face="monospace, monospace" class="">Playground execution failed:<br class="">error: Test.playground:3:23: error: argument passed to call that takes no arguments<br class=""> return triple(self)<br class=""> ~^~~~~</font></blockquote><div class=""><br class=""></div><div class=""><br class=""></div></div><div class="">So the compiler correctly recognizes that “triple(self)” is not a valid call to the instance method. Indeed, it has the wrong arity. From there, it seems to me a small step to reason that, in the case where a function with the proper signature *does* exist, that it should be called.</div><div class=""><br class=""></div><div class=""> • • •</div><div class=""><br class=""></div><div class="">Also, as a minor point, going back to the original code, notice there are two diagnostic messages. The second one says, “use '__lldb_expr_52.' to reference the global function”. However, that does not work, and indeed every time I run the playground the number shown changes.</div><div class=""><br class=""></div><div class="">So it seems that in a playground, the diagnostic is incorrect, as the proposed solution does not work. Is there in fact a way to specify the module for a playground, so as to unambiguously call a global function?</div></div></div></blockquote><div class=""><br class=""></div><div class="">That doesn’t work at the REPL because LLDB is handing you a new module context every time you execute an expression. When you factor this into a playground/framework/executable you can disambiguate with the name of the module.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class=""> • • •</div><div class=""><br class=""></div><div class="">In any case, the proper behavior seems clear-cut to my mind. The shorthand for calling an instance method without “self.” should apply only if there is a matching instance method to call. When there is no instance method which could possibly match, but there is a global function that does, then the unqualified call should resolve to the global function.</div></div></div></blockquote><div class=""><br class=""></div><div class="">You may be able to get away with this by teaching lookup for overloads to pull in global declarations, but you’ll need to adjust the ranking to penalize this as well. This is assuming there aren’t scoping issues we’re ignoring with a rule that, at first blush, seems like common sense. I’m not sure this is StarterBug material - but updating the diagnostic to be more clear would definitely be.</div></div></div></blockquote><br class=""></div><div>This is <i class="">definitely</i> a change that would need to go through swift-evolution. There are a number of potential issues and possibilities for breaking existing code that’s relying on this shadowing behavior, intentionally or unintentionally.</div><div><br class=""></div><div>Jordan</div><div><br class=""></div><br class=""></body></html>