Big fan of this proposal overall, but I do have concerns about the interpretation of :: in qualified lookups, as seen in the Spacecraft.IonThruster::Engine example. This reads to me as searching for the Engine symbol in the Spacecraft.IonThruster package. This isn’t just a matter of associativity, since there is no top-level Engine in the IonThruster package either. So what happens if one is added?
// In module IonThruster
struct Engine { ... }
extension Spacecraft {
struct Engine {
// not the same as the top level type
}
}
// In module NASA
import IonThruster
func makeIonThruster() -> Spacecraft.IonThruster::Engine { ... }
// which Engine does this refer to?
Even if the rule as pitched can successfully disambiguate this situation, it seems potentially very confusing that IonThruster::Engine refers to the top-level type in one context but a nested type in a different context. It also unfortunately prejudices the language against ever supporting native Swift submodules.
I think it would be more consistent to put the module before the whole type: IonThruster::Spacecraft.Engine. The immediate challenge is that IonThruster might export its own top-level Spacecraft type, in addition to extending the one it imported from elsewhere. I believe this can be solved with nesting: IonThruster::(Spacecraft::Spacecraft).Engine would refer to the Engine type nested within the IonThruster module’s extension of the Spacecraft type imported from the Spacecraft module.