| r[paths] | |
| # Paths | |
| r[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: | |
| <!-- ignore: syntax fragment --> | |
| ```rust,ignore | |
| x; | |
| x::y::z; | |
| ``` | |
| ## Types of paths | |
| r[paths.simple] | |
| ### Simple paths | |
| r[paths.simple.syntax] | |
| ```grammar,paths | |
| SimplePath -> | |
| `::`? SimplePathSegment (`::` SimplePathSegment)* | |
| SimplePathSegment -> | |
| IDENTIFIER | `super` | `self` | `crate` | `$crate` | |
| ``` | |
| r[paths.simple.intro] | |
| Simple paths are used in [visibility] markers, [attributes], [macros][mbe], and [`use`] items. For example: | |
| ```rust | |
| use std::io::{self, Write}; | |
| mod m { | |
| #[clippy::cyclomatic_complexity = "0"] | |
| pub (in super) fn f1() {} | |
| } | |
| ``` | |
| r[paths.expr] | |
| ### Paths in expressions | |
| r[paths.expr.syntax] | |
| ```grammar,paths | |
| PathInExpression -> | |
| `::`? PathExprSegment (`::` PathExprSegment)* | |
| PathExprSegment -> | |
| PathIdentSegment (`::` GenericArgs)? | |
| PathIdentSegment -> | |
| IDENTIFIER | `super` | `self` | `Self` | `crate` | `$crate` | |
| GenericArgs -> | |
| `<` GenericArgList? `>` | |
| | `(` TypeList? `)` (`->` TypeNoBounds)? | |
| GenericArgList -> | |
| ( GenericArg `,` )* GenericArg `,`? | |
| TypeList -> | |
| ( Type `,` )* Type `,`? | |
| GenericArg -> | |
| Lifetime | Type | GenericArgsConst | GenericArgsBinding | GenericArgsBounds | |
| GenericArgsConst -> | |
| BlockExpression | |
| | LiteralExpression | |
| | `-` LiteralExpression | |
| | SimplePathSegment | |
| GenericArgsBinding -> | |
| TypePathSegment `=` Type | |
| GenericArgsBounds -> | |
| TypePathSegment `:` Bounds? | |
| ``` | |
| r[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]. | |
| r[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. | |
| ```rust | |
| (0..10).collect::<Vec<_>>(); | |
| Vec::<u8>::with_capacity(1024); | |
| ``` | |
| r[paths.expr.argument-order] | |
| The order of generic arguments is restricted to lifetime arguments, then type arguments, then const arguments, then equality constraints. | |
| r[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. | |
| ```rust | |
| 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. | |
| ``` | |
| ```rust,compile_fail | |
| 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][InferredType] but then semantically treated as a separate kind of [const generic argument]. | |
| r[paths.expr.impl-trait-params] | |
| The synthetic type parameters corresponding to `impl Trait` types are implicit, and these cannot be explicitly specified. | |
| r[paths.qualified] | |
| ## Qualified paths | |
| r[paths.qualified.syntax] | |
| ```grammar,paths | |
| QualifiedPathInExpression -> QualifiedPathType (`::` PathExprSegment)+ | |
| QualifiedPathType -> `<` Type (`as` TypePath)? `>` | |
| QualifiedPathInType -> QualifiedPathType (`::` TypePathSegment)+ | |
| ``` | |
| r[paths.qualified.intro] | |
| Fully qualified paths allow for disambiguating the path for [trait implementations] and for specifying [canonical paths](#canonical-paths). When used in a type specification, it supports using the type syntax specified below. | |
| ```rust | |
| 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. | |
| ``` | |
| r[paths.type] | |
| ### Paths in types | |
| r[paths.type.syntax] | |
| ```grammar,paths | |
| TypePath -> `::`? TypePathSegment (`::` TypePathSegment)* | |
| TypePathSegment -> PathIdentSegment (`::`? GenericArgs)? | |
| ``` | |
| r[paths.type.intro] | |
| Type paths are used within type definitions, trait bounds, and qualified paths. | |
| r[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]. | |
| ```rust | |
| # 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>; | |
| ``` | |
| r[paths.qualifiers] | |
| ## Path qualifiers | |
| r[paths.qualifiers.intro] | |
| Paths can be denoted with various leading qualifiers to change the meaning of how it is resolved. | |
| > [!NOTE] | |
| > [`use` declarations] have additional behaviors and restrictions for `self`, `super`, `crate`, and `$crate`. | |
| r[paths.qualifiers.global-root] | |
| ### `::` | |
| r[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. | |
| r[paths.qualifiers.global-root.edition2018] | |
| > [!EDITION-2018] | |
| > 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. | |
| ```rust | |
| 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); | |
| } | |
| ``` | |
| ```rust,edition2015 | |
| // 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() {} | |
| ``` | |
| r[paths.qualifiers.mod-self] | |
| ### `self` | |
| r[paths.qualifiers.mod-self.intro] | |
| `self` resolves the path relative to the current module. | |
| r[paths.qualifiers.mod-self.restriction] | |
| `self` may only be used as the first segment of a path (without a preceding `::`) or as the last segment (preceded by `::`). | |
| r[paths.qualifiers.mod-self.trailing] | |
| When `self` appears as the last segment of a path, it refers to the entity named by the preceding segment. The preceding path must resolve to a [module], [enumeration], or [trait]. | |
| ```rust | |
| mod m { | |
| pub enum E { V1 } | |
| pub trait Tr {} | |
| pub(in crate::m::self) fn g() {} // OK: Modules can be parents of `self`. | |
| } | |
| type Ty = m::E::self; // OK: Enumerations can be parents of `self`. | |
| fn f<T: m::Tr::self>() {} // OK: Traits can be parents of `self`. | |
| # fn main() { let _: Ty = m::E::V1; } | |
| ``` | |
| ```rust,compile_fail,E0223 | |
| struct S; | |
| type Ty = S::self; // ERROR: Structs cannot be parents of `self`. | |
| # fn main() {} | |
| ``` | |
| > [!NOTE] | |
| > See [items.use.self] for additional rules about `self` in `use` declarations. | |
| r[paths.qualifiers.self-pat] | |
| In a method body, a path which consists of a single `self` segment resolves to the method's self parameter. | |
| ```rust | |
| fn foo() {} | |
| fn bar() { | |
| self::foo(); | |
| } | |
| struct S(bool); | |
| impl S { | |
| fn baz(self) { | |
| self.0; | |
| } | |
| } | |
| # fn main() {} | |
| ``` | |
| r[paths.qualifiers.type-self] | |
| ### `Self` | |
| r[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: | |
| r[paths.qualifiers.type-self.trait] | |
| * In a [trait] definition, it refers to the type implementing the trait. | |
| r[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]. | |
| r[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). | |
| r[paths.qualifiers.type-self.scope] | |
| The scope of `Self` behaves similarly to a generic parameter; see the [`Self` scope] section for more details. | |
| r[paths.qualifiers.type-self.allowed-positions] | |
| `Self` can only be used as the first segment, without a preceding `::`. | |
| r[paths.qualifiers.type-self.no-generics] | |
| The `Self` path cannot include generic arguments (as in `Self::<i32>`). | |
| ```rust | |
| 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>>, | |
| } | |
| ``` | |
| r[paths.qualifiers.super] | |
| ### `super` | |
| r[paths.qualifiers.super.intro] | |
| `super` in a path resolves to the parent module. | |
| r[paths.qualifiers.super.allowed-positions] | |
| It may only be used in leading segments of the path, possibly after an initial `self` segment. | |
| ```rust | |
| mod a { | |
| pub fn foo() {} | |
| } | |
| mod b { | |
| pub fn foo() { | |
| super::a::foo(); // call a's foo function | |
| } | |
| } | |
| # fn main() {} | |
| ``` | |
| r[paths.qualifiers.super.repetition] | |
| `super` may be repeated several times after the first `super` or `self` to refer to ancestor modules. | |
| ```rust | |
| 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() {} | |
| ``` | |
| r[paths.qualifiers.crate] | |
| ### `crate` | |
| r[paths.qualifiers.crate.intro] | |
| `crate` resolves the path relative to the current crate. | |
| r[paths.qualifiers.crate.allowed-positions] | |
| `crate` can only be used as the first segment, without a preceding `::`. | |
| ```rust | |
| fn foo() {} | |
| mod a { | |
| fn bar() { | |
| crate::foo(); | |
| } | |
| } | |
| # fn main() {} | |
| ``` | |
| r[paths.qualifiers.macro-crate] | |
| ### `$crate` | |
| r[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 `::`. | |
| r[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. | |
| ```rust | |
| pub fn increment(x: u32) -> u32 { | |
| x + 1 | |
| } | |
| #[macro_export] | |
| macro_rules! inc { | |
| ($x:expr) => ( $crate::increment($x) ) | |
| } | |
| # fn main() { } | |
| ``` | |
| r[paths.canonical] | |
| ## Canonical paths | |
| r[paths.canonical.intro] | |
| Each item defined in a module or implementation has a *canonical path* that corresponds to where within its crate it is defined. | |
| r[paths.canonical.alias] | |
| All other paths to these items are aliases. | |
| r[paths.canonical.def] | |
| The canonical path is defined as a *path prefix* appended by the path segment the item itself defines. | |
| r[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. | |
| r[paths.canonical.module-prefix] | |
| The path prefix for modules is the canonical path to that module. | |
| r[paths.canonical.bare-impl-prefix] | |
| For bare implementations, it is the canonical path of the item being implemented surrounded by <span class="parenthetical">angle (`<>`)</span> brackets. | |
| r[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 <span class="parenthetical">angle (`<>`)</span> brackets. | |
| r[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. | |
| ```rust | |
| // 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() {} | |
| ``` | |
| [`$crate`]: macro.decl.hygiene.crate | |
| [implementations]: items/implementations.md | |
| [items]: items.md | |
| [literal]: expressions/literal-expr.md | |
| [use declarations]: items/use-declarations.md | |
| [`Self` scope]: names/scopes.md#self-scope | |
| [`use`]: items/use-declarations.md | |
| [attributes]: attributes.md | |
| [const generic argument]: items.generics.const.argument | |
| [enumeration]: items/enumerations.md | |
| [expressions]: expressions.md | |
| [extern prelude]: names/preludes.md#extern-prelude | |
| [implementation]: items/implementations.md | |
| [inferred const]: items.generics.const.inferred | |
| [macro transcribers]: macros-by-example.md | |
| [macros]: macros.md | |
| [mbe]: macros-by-example.md | |
| [module]: items/modules.md | |
| [patterns]: patterns.md | |
| [struct]: items/structs.md | |
| [trait implementations]: items/implementations.md#trait-implementations | |
| [trait]: items/traits.md | |
| [traits]: items/traits.md | |
| [types]: types.md | |
| [union]: items/unions.md | |
| [`use` declarations]: items/use-declarations.md | |
| [value namespace]: names/namespaces.md | |
| [visibility]: visibility-and-privacy.md |