What are the valid path roots in the use keyword?

With the module system being revamped for the 2018 edition, the functioning of the use keyword has changed. What are the valid paths that can go after the use keyword?


Solution 1:

Paths in use statements can only start in the following ways:

  • name of an extern crate: then it refers to that extern crate
  • crate: refers to the (top level of your) own crate
  • self: refers to the current module
  • super: refers to the parent module
  • other name: in this case, it looks for that name relative to the current module

An example demonstrating all kinds of use-paths (Playground):

pub const NAME: &str = "peter";
pub const WEIGHT: f32 = 3.1;

mod inner {
    mod child {
        pub const HEIGHT: f32 = 0.3;
        pub const AGE: u32 = 3;
    }

    // Different kinds of uses
    use base64::encode;   // Extern crate `base64`
    use crate::NAME;      // Own crate (top level module)
    use self::child::AGE; // Current module
    use super::WEIGHT;    // Parent module (in this case, this is the same 
                          // as `crate`)
    use child::HEIGHT;    // If the first name is not `crate`, `self` or 
                          // `super` and it's not the name of an extern 
                          // crate, it is a path relative to the current
                          // module (as if it started with `self`)
}

This use statement behavior changed with Rust 2018 (available in Rust ≥ 1.31)). Read this guide for more information about use statements and how they changed in Rust 2018.

Solution 2:

Your path can begin in 2 different ways: absolute or relative:

  • Your path can begin with a crate name, or the crate keyword to name the current crate:

    struct Foo;
    
    mod module {
        use crate::Foo; // Use `Foo` from the current crate.
        use serde::Serialize; // Use `Serialize` from the serde crate.
    }
    
    fn main() {}
    
  • Otherwise, the root is implicitely self, that means that your path will be relative to your current module:

    mod module {
        pub struct Foo;
        pub struct Bar;
    }
    
    use module::Foo; // By default, you are in the `self` (current) module.
    use self::module::Bar; // Explicit `self`.
    

    In this context, you can use super to access to the outer module:

    struct Foo;
    
    mod module {
        use super::Foo; // Access `Foo` from the outer module.
    }