This makes me uncomfortable. It feels fragile. For example, if I have an external crate called “collections” that has it’s own HashMap module, then, both of these compile, but, mean two different things:
use std::collections;
use collections::HashMap;
and
use collections::HashMap;
use std::collections;
So, when re-factoring (and re-factoring tools like in IDE’s) would need to analyze use statements and such before re-ordering them. This might be unavoidable, but, if we required a specific keyword/pre-fix for external crate usages in all cases, might that prevent this situation entirely? Would the downside of that be worse or better than this sort of ambiguity?
In other words, the above, to get the “collections” crate HashMap would have to be:
use ::collections::HashMap;
use std::collections;
or
use std::collections;
use ::collections::HashMap;
which would both be equivalent to each other, but, would be different from:
use std::collections;
use collections::HashMap;
and
use collections::HashMap;
use std::collections;
would be a compiler error along the lines of, “Unable to resolve collections::HashMap”.
Now, this would break non-use prelude paths like:
let x = std::time::SystemTime.now();
which would have to be:
let x = ::std::time::SystemTime.now();
instead. If that is too much of a backwards compatibility issue, then, what if the rule was relaxed to allow only standard prelude items to be resolved without the leading :: instead of prelude AND external crate items. This would mean your rule:
Would instead become:
Would that not get rid of the ambiguous cases? Would it be backwards compatible? Is there some big ergonomic issue that this brings up that outweighs the benefits to a lack of ambiguity?