Scoping rules for modules

While learning about Rust modules, I noticed that the use directive is always relative to crate root. This produces surprising results like below:

mod foo {
    pub fn f() { println!("foo::f()"); }
}

mod bar {
    mod foo {
        pub fn f() { println!("bar::foo::f()"); }
    }

    pub fn test() {
        use foo::f as foo_f;
        foo_f(); // calls foo::f() instead of bar::foo:f() !
        
        foo::f(); // calls bar::foo:f()
    }
}

fn main() {
    bar::test();
}

The fix is trivial (use self::foo::f). But I'm curious: why was this design chosen? It goes against common experience for anyone coming from C++, C# etc.

1 Like

Yeah, this also surprised me a lot while I was learning Rust. If the path rules for use items were the same as for all other paths, then you'd have to

use ::std::collections::HashMap;

instead of

use std::collections::HashMap;