Paths - The Rust Reference

## Keyboard shortcuts

Press `←` or `→` to navigate between chapters

Press `S` or `/` to search in the book

Press `?` to show this help

Press `Esc` to hide this help

[paths]

# Paths

[paths.intro]

A path is a sequence of one or more path segments separated by `::` tokens. Paths are used to refer to items, values, types, macros, and attributes.

Two examples of simple paths consisting of only identifier segments:

    x;
    x::y::z;

## Types of paths

[paths.simple]

### Simple paths

[paths.simple.syntax]

Syntax
SimplePath →
::? SimplePathSegment ( :: SimplePathSegment )*

SimplePathSegment →
IDENTIFIER | super | self | crate | $crate

[paths.simple.intro]

Simple paths are used in visibility markers, attributes, macros, and `use` items. For example:

    #![allow(unused)]
    fn main() {
    use std::io::{self, Write};
    mod m {
        #[clippy::cyclomatic_complexity = "0"]
        pub (in super) fn f1() {}
    }
    }

[paths.expr]

### Paths in expressions

[paths.expr.syntax]

Syntax
PathInExpression →
::? PathExprSegment ( :: PathExprSegment )*

PathExprSegment →
PathIdentSegment ( :: GenericArgs )?

PathIdentSegment →
IDENTIFIER | super | self | Self | crate | $crate

GenericArgs →
< >
| < ( GenericArg , )* GenericArg ,? >

GenericArg →
Lifetime | Type | GenericArgsConst | GenericArgsBinding | GenericArgsBounds

GenericArgsConst →
BlockExpression
| LiteralExpression
| - LiteralExpression
| SimplePathSegment

GenericArgsBinding →
IDENTIFIER GenericArgs? = Type

GenericArgsBounds →
IDENTIFIER GenericArgs? : TypeParamBounds

[paths.expr.intro]

Paths in expressions allow for paths with generic arguments to be specified. They are used in various places in expressions and patterns.

[paths.expr.turbofish]

The `::` token is required before the opening `<` for generic arguments to avoid ambiguity with the less-than operator. This is colloquially known as “turbofish” syntax.

    #![allow(unused)]
    fn main() {
    (0..10).collect::<Vec<_>>();
    Vec::<u8>::with_capacity(1024);
    }

[paths.expr.argument-order]

The order of generic arguments is restricted to lifetime arguments, then type arguments, then const arguments, then equality constraints.

[paths.expr.complex-const-params]

Const arguments must be surrounded by braces unless they are a literal, an inferred const, or a single segment path. An inferred const may not be surrounded by braces.

    #![allow(unused)]
    fn main() {
    mod m {
        pub const C: usize = 1;
    }
    const C: usize = m::C;
    fn f<const N: usize>() -> [u8; N] { [0; N] }

    let _ = f::<1>(); // Literal.
    let _: [_; 1] = f::<_>(); // Inferred const.
    let _: [_; 1] = f::<(((_)))>(); // Inferred const.
    let _ = f::<C>(); // Single segment path.
    let _ = f::<{ m::C }>(); // Multi-segment path must be braced.
    }

    #![allow(unused)]
    fn main() {
    fn f<const N: usize>() -> [u8; N] { [0; _] }
    let _: [_; 1] = f::<{ _ }>();
    //                    ^ ERROR `_` not allowed here
    }

> Note

> In a generic argument list, an inferred const is parsed as an inferred type but then semantically treated as a separate kind of const generic argument.

[paths.expr.impl-trait-params]

The synthetic type parameters corresponding to `impl Trait` types are implicit, and these cannot be explicitly specified.

[paths.qualified]

## Qualified paths

[paths.qualified.syntax]

Syntax
QualifiedPathInExpression → QualifiedPathType ( :: PathExprSegment )+

QualifiedPathType → < Type ( as TypePath )? >

QualifiedPathInType → QualifiedPathType ( :: TypePathSegment )+

[paths.qualified.intro]

Fully qualified paths allow for disambiguating the path for trait implementations and for specifying canonical paths. When used in a type specification, it supports using the type syntax specified below.

    #![allow(unused)]
    fn main() {
    struct S;
    impl S {
        fn f() { println!("S"); }
    }
    trait T1 {
        fn f() { println!("T1 f"); }
    }
    impl T1 for S {}
    trait T2 {
        fn f() { println!("T2 f"); }
    }
    impl T2 for S {}
    S::f();  // Calls the inherent impl.
    <S as T1>::f();  // Calls the T1 trait function.
    <S as T2>::f();  // Calls the T2 trait function.
    }

[paths.type]

### Paths in types

[paths.type.syntax]

Syntax
TypePath → ::? TypePathSegment ( :: TypePathSegment )*

TypePathSegment → PathIdentSegment ( ::? ( GenericArgs | TypePathFn ) )?

TypePathFn → ( TypePathFnInputs? ) ( -> TypeNoBounds )?

TypePathFnInputs → Type ( , Type )* ,?

[paths.type.intro]

Type paths are used within type definitions, trait bounds, type parameter bounds, and qualified paths.

[paths.type.turbofish]

Although the `::` token is allowed before the generics arguments, it is not required because there is no ambiguity like there is in PathInExpression.

    #![allow(unused)]
    fn main() {
    mod ops {
        pub struct Range<T> {f1: T}
        pub trait Index<T> {}
        pub struct Example<'a> {f1: &'a i32}
    }
    struct S;
    impl ops::Index<ops::Range<usize>> for S { /*...*/ }
    fn i<'a>() -> impl Iterator<Item = ops::Example<'a>> {
        // ...
       const EXAMPLE: Vec<ops::Example<'static>> = Vec::new();
       EXAMPLE.into_iter()
    }
    type G = std::boxed::Box<dyn std::ops::FnOnce(isize) -> isize>;
    }

[paths.qualifiers]

## Path qualifiers

Paths can be denoted with various leading qualifiers to change the meaning of how it is resolved.

[paths.qualifiers.global-root]

### `::`

[paths.qualifiers.global-root.intro]

Paths starting with `::` are considered to be global paths where the segments of the path start being resolved from a place which differs based on edition. Each identifier in the path must resolve to an item.

[paths.qualifiers.global-root.edition2018]

> 2018 Edition differences

> In the 2015 Edition, identifiers resolve from the “crate root” (`crate::` in the 2018 edition), which contains a variety of different items, including external crates, default crates such as `std` or `core`, and items in the top level of the crate (including `use` imports).

> Beginning with the 2018 Edition, paths starting with `::` resolve from crates in the extern prelude. That is, they must be followed by the name of a crate.

    #![allow(unused)]
    fn main() {
    pub fn foo() {
        // In the 2018 edition, this accesses `std` via the extern prelude.
        // In the 2015 edition, this accesses `std` via the crate root.
        let now = ::std::time::Instant::now();
        println!("{:?}", now);
    }
    }

    // 2015 Edition
    mod a {
        pub fn foo() {}
    }
    mod b {
        pub fn foo() {
            ::a::foo(); // call `a`'s foo function
            // In Rust 2018, `::a` would be interpreted as the crate `a`.
        }
    }
    fn main() {}

[paths.qualifiers.mod-self]

### `self`

[paths.qualifiers.mod-self.intro]

`self` resolves the path relative to the current module.

[paths.qualifiers.mod-self.restriction]

`self` can only be used as the first segment, without a preceding `::`.

[paths.qualifiers.self-pat]

In a method body, a path which consists of a single `self` segment resolves to the method’s self parameter.

    fn foo() {}
    fn bar() {
        self::foo();
    }
    struct S(bool);
    impl S {
      fn baz(self) {
            self.0;
        }
    }
    fn main() {}

[paths.qualifiers.type-self]

### `Self`

[paths.qualifiers.type-self.intro]

`Self`, with a capital “S”, is used to refer to the current type being implemented or defined. It may be used in the following situations:

[paths.qualifiers.type-self.trait]

- In a trait definition, it refers to the type implementing the trait.

[paths.qualifiers.type-self.impl]

- In an implementation, it refers to the type being implemented. When implementing a tuple or unit struct, it also refers to the constructor in the value namespace.

[paths.qualifiers.type-self.type]

- In the definition of a struct, enumeration, or union, it refers to the type being defined. The definition is not allowed to be infinitely recursive (there must be an indirection).

[paths.qualifiers.type-self.scope]

The scope of `Self` behaves similarly to a generic parameter; see the `Self` scope section for more details.

[paths.qualifiers.type-self.allowed-positions]

`Self` can only be used as the first segment, without a preceding `::`.

[paths.qualifiers.type-self.no-generics]

The `Self` path cannot include generic arguments (as in `Self::<i32>`).

    #![allow(unused)]
    fn main() {
    trait T {
        type Item;
        const C: i32;
        // `Self` will be whatever type that implements `T`.
        fn new() -> Self;
        // `Self::Item` will be the type alias in the implementation.
        fn f(&self) -> Self::Item;
    }
    struct S;
    impl T for S {
        type Item = i32;
        const C: i32 = 9;
        fn new() -> Self {           // `Self` is the type `S`.
            S
        }
        fn f(&self) -> Self::Item {  // `Self::Item` is the type `i32`.
            Self::C                  // `Self::C` is the constant value `9`.
        }
    }

    // `Self` is in scope within the generics of a trait definition,
    // to refer to the type being defined.
    trait Add<Rhs = Self> {
        type Output;
        // `Self` can also reference associated items of the
        // type being implemented.
        fn add(self, rhs: Rhs) -> Self::Output;
    }

    struct NonEmptyList<T> {
        head: T,
        // A struct can reference itself (as long as it is not
        // infinitely recursive).
        tail: Option<Box<Self>>,
    }
    }

[paths.qualifiers.super]

### `super`

[paths.qualifiers.super.intro]

`super` in a path resolves to the parent module.

[paths.qualifiers.super.allowed-positions]

It may only be used in leading segments of the path, possibly after an initial `self` segment.

    mod a {
        pub fn foo() {}
    }
    mod b {
        pub fn foo() {
            super::a::foo(); // call a's foo function
        }
    }
    fn main() {}

[paths.qualifiers.super.repetition]

`super` may be repeated several times after the first `super` or `self` to refer to ancestor modules.

    mod a {
        fn foo() {}

        mod b {
            mod c {
                fn foo() {
                    super::super::foo(); // call a's foo function
                    self::super::super::foo(); // call a's foo function
                }
            }
        }
    }
    fn main() {}

[paths.qualifiers.crate]

### `crate`

[paths.qualifiers.crate.intro]

`crate` resolves the path relative to the current crate.

[paths.qualifiers.crate.allowed-positions]

`crate` can only be used as the first segment, without a preceding `::`.

    fn foo() {}
    mod a {
        fn bar() {
            crate::foo();
        }
    }
    fn main() {}

[paths.qualifiers.macro-crate]

### `$crate`

[paths.qualifiers.macro-crate.allowed-positions]

`$crate` is only used within macro transcribers, and can only be used as the first segment, without a preceding `::`.

[paths.qualifiers.macro-crate.hygiene]

`$crate` will expand to a path to access items from the top level of the crate where the macro is defined, regardless of which crate the macro is invoked.

    pub fn increment(x: u32) -> u32 {
        x + 1
    }

    #[macro_export]
    macro_rules! inc {
        ($x:expr) => ( $crate::increment($x) )
    }
    fn main() { }

[paths.canonical]

## Canonical paths

[paths.canonical.intro]

Items defined in a module or implementation have a canonical path that corresponds to where within its crate it is defined.

[paths.canonical.alias]

All other paths to these items are aliases.

[paths.canonical.def]

The canonical path is defined as a path prefix appended by the path segment the item itself defines.

[paths.canonical.non-canonical]

Implementations and use declarations do not have canonical paths, although the items that implementations define do have them. Items defined in block expressions do not have canonical paths. Items defined in a module that does not have a canonical path do not have a canonical path. Associated items defined in an implementation that refers to an item without a canonical path, e.g. as the implementing type, the trait being implemented, a type parameter or bound on a type parameter, do not have canonical paths.

[paths.canonical.module-prefix]

The path prefix for modules is the canonical path to that module.

[paths.canonical.bare-impl-prefix]

For bare implementations, it is the canonical path of the item being implemented surrounded by angle (`<>`) brackets.

[paths.canonical.trait-impl-prefix]

For trait implementations, it is the canonical path of the item being implemented followed by `as` followed by the canonical path to the trait all surrounded in angle (`<>`) brackets.

[paths.canonical.local-canonical-path]

The canonical path is only meaningful within a given crate. There is no global namespace across crates; an item’s canonical path merely identifies it within the crate.

    // Comments show the canonical path of the item.

    mod a { // crate::a
        pub struct Struct; // crate::a::Struct

        pub trait Trait { // crate::a::Trait
            fn f(&self); // crate::a::Trait::f
        }

        impl Trait for Struct {
            fn f(&self) {} // <crate::a::Struct as crate::a::Trait>::f
        }

        impl Struct {
            fn g(&self) {} // <crate::a::Struct>::g
        }
    }

    mod without { // crate::without
        fn canonicals() { // crate::without::canonicals
            struct OtherStruct; // None

            trait OtherTrait { // None
                fn g(&self); // None
            }

            impl OtherTrait for OtherStruct {
                fn g(&self) {} // None
            }

            impl OtherTrait for crate::a::Struct {
                fn g(&self) {} // None
            }

            impl crate::a::Trait for OtherStruct {
                fn f(&self) {} // None
            }
        }
    }

    fn main() {}