Everything I've read about 2018 edition suggests that the following should not work, but it does:
// (for an easy-to-compile example, I picked a common crate
// that has no dependencies)
extern crate dtoa as d;
mod foo {
use d::write; // How is this line valid in 2018 edition?
pub fn bar() {
let mut buf = Vec::new();
write(&mut buf, 2.71828f64).unwrap();
println!("{:?}", buf);
}
}
fn main() {
foo::bar()
}
extern crate dtoa as d; creates a crate item at the path ::d.
use d::write is equivalent to use ::d::write.
Versus the 2018 edition:
extern crate dtoa as d; creates a crate item at the path crate::d.
use d::writeis not equivalent to use crate::d::write. It searches the prelude for anything called d and finds nothing, and so it becomes equivalent to use self::d::write, which does not exist.
No. Just as before, it still creates at at ::d. extern crate _ as _ is not equivalent to extern crate _ followed by a re-export. Your quote is about what you need to do when you do remove the extern crate item.
Regardless, the compiler does not look in :: to resolve names according to all of the discussion I have seen thus far; the behavior was discussed as follows:
(fundamental change of 2018 edition): The crate root is no longer implicitly searched during name resolution.
(stable feature extern_prelude): All crates provided by --extern flags to the compiler appear in the prelude.
(stable feature uniform_paths): self:: is implicitly searched during name resolution.
Clearly, this description is inadequate. d is not among the --extern flags, and is not visible in self. Yet it is available for name resolution inside submodules.
Furthermore, this seems pretty arbitrary. Consider what happens if the extern crate is moved into a module:
mod lol {
extern crate dtoa as d;
mod foo {
use ::d::write;
pub fn bar() {
let mut buf = Vec::new();
write(&mut buf, 2.71828f64).unwrap();
println!("{:?}", buf);
}
}
fn main() {
foo::bar()
}
}
Now it stops compiling as it can no longer find d. So apparently, extern crate a as b; makes b available for name resolution everywhere if and only if it appears in the crate root. This is a pretty specific and complex rule to have added to our "simplified" import scheme!