[swift-evolution] [Discussion] File-level declarations having highest priority for shadowing

Xiaodi Wu xiaodi.wu at gmail.com
Mon Jun 20 14:27:55 CDT 2016

On Mon, Jun 20, 2016 at 2:17 PM, Charlie Monroe <charlie at charliemonroe.net>

> IMHO file-level scope *is* special. Aside from the fact that some
> declarations (e.g. protocols) are only valid at file-level scope, the way I
> see it, it's a scope where you have *global* symbols to the file - i.e.
> they should be available *globally* anywhere within the file.
> I undestand that this goes against the overall hierarchy of shadowing,
> though, which is why I've proposed an alternative: the compiler shouldn't
> (in case of invoking methods) just check the base name, but it should do a
> more thorough search, looking at the arguments as well. Just like when
> you're overloading a method.

I could support a proposal for that alternative.

> On Jun 20, 2016, at 8:59 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
> I can see how this is a problem, but I don't like this solution for the
> same reasoning that Jordan provided in the bug. Namely, the general rule is
> that the inner scope shadows the outer scope. This would be a very strange
> exception that you're proposing.
> I'd rather cope temporarily with the current limitation, which as you
> mentioned has a workaround everywhere except in Playgrounds; in
> Playgrounds, there isn't any reason why you couldn't just rename one or the
> other.
> On Mon, Jun 20, 2016 at 13:55 Charlie Monroe via swift-evolution <
> swift-evolution at swift.org> wrote:
>> I've filed this previously as a compiler bug, but was told to discuss
>> this here (https://bugs.swift.org/browse/SR-1772).
>> Motivation:
>> Consider the following code:
>> private func _validateAccount(name: String, existingAccounts: [Account])
>> -> Bool {
>>     // Logic goes here...
>> }
>> class MyController {
>>     private func _validateAccount(name: String) -> Bool {
>>         let accounts = self.accounts
>> // Error: Extra argument 'existingAccounts' in call
>>         return _validateAccount(name, existingAccounts: accounts)
>>     }
>> }
>> _validateAccount(name:, existingAccounts:) is declared at file-level
>> since it is used in two separate controllers (my example comes from an app
>> with accounts and the check is done during creation + when renaming) and
>> then a similar method (with less arguments) is declared on the controllers.
>> Currently, the compiler gives an error about ambiguous use of
>> _validateAccount, since it's declared on MyController as well which is
>> taking precedence, even though the number of arguments is different (and
>> the compiler is only checking base names, not arguments).
>> As Jordan Rose mentioned in a comment to my report, solution to this is
>> to specify the function using Module._validateAccount, but this is not
>> applicable to Playgrounds.
>> This is partially an issue of the ongoing discussion of various name
>> collisions between modules, but in this particular case, it's one single
>> file.
>> I propose that file-level symbols take precedence over any reference to
>> current type's members, unless explicit self is specified, or at least when
>> it comes to calling a method, the type checker goes up the scope hierarchy
>> to see if there isn't a function satisfying the arguments.
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160620/e7f3674c/attachment.html>

More information about the swift-evolution mailing list