A path is a sequence of one or more path segments logically separated by a namespace qualifier (::
). If a path consists of only one segment, it refers to either an item or a variable in a local control scope. If a path has multiple segments, it always refers to an item.
Two examples of simple paths consisting of only identifier segments:
x; x::y::z;
Syntax
SimplePath :
::
? SimplePathSegment (::
SimplePathSegment)*SimplePathSegment :
IDENTIFIER |super
|self
|crate
|$crate
Simple paths are used in visibility markers, attributes, macros, and use
items. Examples:
#![allow(unused)] fn main() { use std::io::{self, Write}; mod m { #[clippy::cyclomatic_complexity = "0"] pub (in super) fn f1() {} } }
Syntax
PathInExpression :
::
? PathExprSegment (::
PathExprSegment)*PathExprSegment :
PathIdentSegment (::
GenericArgs)?PathIdentSegment :
IDENTIFIER |super
|self
|Self
|crate
|$crate
GenericArgs :
<
>
|<
GenericArgsLifetimes,
?>
|<
GenericArgsTypes,
?>
|<
GenericArgsBindings,
?>
|<
GenericArgsTypes,
GenericArgsBindings,
?>
|<
GenericArgsLifetimes,
GenericArgsTypes,
?>
|<
GenericArgsLifetimes,
GenericArgsBindings,
?>
|<
GenericArgsLifetimes,
GenericArgsTypes,
GenericArgsBindings,
?>
GenericArgsLifetimes :
Lifetime (,
Lifetime)*GenericArgsTypes :
Type (,
Type)*GenericArgsBindings :
GenericArgsBinding (,
GenericArgsBinding)*GenericArgsBinding :
IDENTIFIER=
Type
Paths in expressions allow for paths with generic arguments to be specified. They are used in various places in expressions and patterns.
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); }
Syntax
QualifiedPathInExpression :
QualifiedPathType (::
PathExprSegment)+QualifiedPathType :
<
Type (as
TypePath)?>
QualifiedPathInType :
QualifiedPathType (::
TypePathSegment)+
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. }
Syntax
TypePath :
::
? TypePathSegment (::
TypePathSegment)*TypePathSegment :
PathIdentSegment::
? (GenericArgs | TypePathFn)?TypePathFn :
(
TypePathFnInputs?)
(->
Type)?
Type paths are used within type definitions, trait bounds, type parameter bounds, and qualified paths.
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 can be denoted with various leading qualifiers to change the meaning of how it is resolved.
::
Paths starting with ::
are considered to be global paths where the segments of the path start being resolved from the crate root. Each identifier in the path must resolve to an item.
Edition Differences: In the 2015 Edition, the crate root contains a variety of different items, including external crates, default crates such as
std
andcore
, and items in the top level of the crate (includinguse
imports).Beginning with the 2018 Edition, paths starting with
::
can only reference crates.
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() {}
self
self
resolves the path relative to the current module. self
can only be used as the first segment, without a preceding ::
.
fn foo() {} fn bar() { self::foo(); } fn main() {}
Self
Self
, with a capital "S", is used to refer to the implementing type within traits and implementations.
Self
can only be used as the first segment, without a preceding ::
.
#![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`. } } }
super
super
in a path resolves to the parent module. 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() {}
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() {}
crate
crate
resolves the path relative to the current crate. crate
can only be used as the first segment, without a preceding ::
.
fn foo() {} mod a { fn bar() { crate::foo(); } } fn main() {}
$crate
$crate
is only used within macro transcribers, and can only be used as the first segment, without a preceding ::
. $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() { }
Items defined in a module or implementation have a canonical path that corresponds to where within its crate it is defined. All other paths to these items are aliases. The canonical path is defined as a path prefix appended by the path segment the item itself defines.
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.
The path prefix for modules is the canonical path to that module. For bare implementations, it is the canonical path of the item being implemented surrounded by angle (<>
) brackets. 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.
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 { // ::a pub struct Struct; // ::a::Struct pub trait Trait { // ::a::Trait fn f(&self); // ::a::Trait::f } impl Trait for Struct { fn f(&self) {} // <::a::Struct as ::a::Trait>::f } impl Struct { fn g(&self) {} // <::a::Struct>::g } } mod without { // ::without fn canonicals() { // ::without::canonicals struct OtherStruct; // None trait OtherTrait { // None fn g(&self); // None } impl OtherTrait for OtherStruct { fn g(&self) {} // None } impl OtherTrait for ::a::Struct { fn g(&self) {} // None } impl ::a::Trait for OtherStruct { fn f(&self) {} // None } } } fn main() {}
© 2010 The Rust Project Developers
Licensed under the Apache License, Version 2.0 or the MIT license, at your option.
https://doc.rust-lang.org/reference/paths.html