> On Sep 26, 2017, at 18:02, Robert Widmann via swift-dev <swift-dev@swift.org> 
> wrote:
> 
>> 
>> On Sep 25, 2017, at 10:01 AM, Nevin Brackett-Rozinsky 
>> <nevin.brackettrozin...@gmail.com <mailto:nevin.brackettrozin...@gmail.com>> 
>> wrote:
>> 
>> func triple(_ x: Int) -> Int {
>>     return 3 * x
>> }
>> 
>> extension Int {
>>     func triple() -> Int {
>>         return triple(self)     // Error here
>>     }
>> }
>> 
>> 
>> The error reads:
>> 
>> Playground execution failed:
>> error: Test.playground:5:16: error: use of 'triple' refers to instance 
>> method 'triple()' rather than global function 'triple' in module 
>> '__lldb_expr_52'
>>         return triple(self)     // Error here
>>                ^
>> Test.playground:5:16: note: use '__lldb_expr_52.' to reference the global 
>> function in module '__lldb_expr_52'
>>         return triple(self)     // Error here
>>                ^
>>                __lldb_expr_52.
>> 
>> 
>> Notice where the error says, “use of 'triple' refers to instance method 
>> 'triple()' rather than global function 'triple'”.
>> 
>> 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.
>> 
>> 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:
>> 
>> 
>> extension Int {
>>     func triple() -> Int {
>>         return triple(self)     // Error here
>>     }
>> }
>> 
>> 
>> This time the error reads:
>> 
>> Playground execution failed:
>> error: Test.playground:3:23: error: argument passed to call that takes no 
>> arguments
>>         return triple(self)
>>                      ~^~~~~
>> 
>> 
>> 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.
>> 
>>  • • •
>> 
>> 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.
>> 
>> 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?
> 
> 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.
> 
>> 
>>  • • •
>> 
>> 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.
> 
> 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.

This is definitely 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.

Jordan


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

Reply via email to