Paths
A path is a sequence of one or more path components logically separated by
namespace qualifiers (::
). If a path consists of only one component, it may
refer to either an item or a variable in a local control
scope. If a path has multiple components, it refers to an item.
Every item has a canonical path within its crate, but the path naming an item 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.
Two examples of simple paths consisting of only identifier components:
x;
x::y::z;
Path components are usually identifiers, but they may
also include angle-bracket-enclosed lists of type arguments. In
expression context, the type argument list is given
after a ::
namespace qualifier in order to disambiguate it from a
relational expression involving the less-than symbol (<
). In type
expression context, the final namespace qualifier is omitted.
Two examples of paths with type arguments:
# #![allow(unused_variables)] #fn main() { # struct HashMap<K, V>(K,V); # fn f() { # fn id<T>(t: T) -> T { t } type T = HashMap<i32,String>; // Type arguments used in a type expression let x = id::<i32>(10); // Type arguments used in a call expression # } #}
Types of paths
Simple paths
Syntax
SimplePath :
::
? PathSegmentIdentifier (::
PathSegmentIdentifier)*PathSegmentIdentifier :
IDENTIFIER |super
|self
|Self
FIXME
Simple paths are used on pub
markers, macro invocations and use
items.
Paths in expressions
Syntax
PathInExpr :
::
? PathSegmentIdentifier (::
(PathSegmentIdentifier | GenericsForType) )*QualifiedPathInExpr :
<
type_ (as
TypePath)?>
::
PathInExpr
Paths in types
Syntax
TypePath :
::
? TypePathElement (::
TypePathElement)*TypePathElement :
PathSegmentIdentifier (GenericsForType | FunctionSignature)?GenericsForType :
<
(LifetimeParams (,
TypeParamsForTypes)? (,
BindingParams)?,
? )?>
|<
TypeParamsForTypes (,
BindingParams)?,
?>
|<
BindingParams,
?>
TypeParamsForTypes :
Type (,
Type)*BindingParams :
TypeBindingParam (,
TypeBindingParam)*TypeBindingParam :
IDENTIFIER=
type_ FIXME
Canonical paths
Qualified paths
Syntax
Qualified_TypePath_ :
<
Type (as
TypePath)?>
::
TypePath FIXME
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 component 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() {}