Fully-Qualified Lookups
- Proposal: SE-NNNN
- Authors: Kyle Sluder
- Review Manager: TBD
- Status: Pitch
Introduction
We propose a syntax for unambiguously referencing any symbol, regardless of local shadowing.
Motivation
Swift currently lacks a way to reference symbols in the global namespace that have been shadowed by closer declarations. The following example illustrates the issue:
struct Swift {
// This is a custom struct that shadows the implicitly-imported Swift namespace.
// While naming a struct `Swift` may be inadvisable, other names are not reserved.
// Any two modules might choose to export structs with the same name.
// Importing both in one file will cause one to shadow the other.
}
func dump(_ thing: Any) -> Void {
// This is a custom function that clients call to produce extra information when dumping objects.
print("Custom dump function called!")
// This causes infinite recursion, because `func dump()` shadows `Swift.dump()`.
dump(thing)
// This causes a compiler error, because `struct Swift` shadows the implicit `import Swift`.
Swift.dump(thing)
}
Proposed solution
We propose the prefix _.
to force fully-qualified lookup. This prefix is the Swift analogue of C++’s scope resolution operator ::
when used as a prefix.
When Swift encounters an identifier expression that begins with _.
, the portion of the identifier expression following the period will be looked up in the unnamed global namespace. The global namespace consists of the following identifiers:
- The names of all imported modules, including the implicitly imported
Swift
module. - The reserved name
Self
, which contains all top-level identifiers visible from the file being compiled.
The Self
identifier allows clients to work around declarations which shadow top-level declarations, without having to build the name of their module into the source file. For example:
private func isGreater(_ a: Any, _ b: Any) -> Bool {
return false
}
public enum MyHelpers {
static func isGreater(_ a: Int, _ b: Int) -> Bool {
return _.Self.isGreater(a, b)
}
}
Detailed design
The postfix-expression production in the grammar gains a new alternative:
postfix-expression → fully-qualified-identifier-expression
The fully-qualified-identifier-expression production is defined as follows:
fully-qualified-identifier-expression → _. explicit-member-expression
Source compatibility
This is a source-compatible change. The _.
prefix is currently not valid in any expression, and the use of Self
does not conflict with any existing uses.
Effect on ABI stability
This proposal does not affect ABI.
Effect on API resilience
This proposal does not affect API resilience.
Alternatives considered
@beccadax has previously opened up a discussion with several ideas, such as @qualified
, #Modules
, and ::
. To my knowledge, this discussion did not address the issue of shadowed top-level declarations.