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

Charlie Monroe charlie at charliemonroe.net
Mon Jun 20 14:17:08 CDT 2016


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.


> 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 <mailto: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 <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 <mailto:swift-evolution at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution <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/7052e14c/attachment.html>


More information about the swift-evolution mailing list