blob: 9bf6e1ec6ac5904bea36b870196511fd9fcff44c [file] [log] [blame] [view] [edit]
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 ->
`<` `>`
| `<` ( GenericArg `,` )* GenericArg `,`? `>`
GenericArg ->
Lifetime | Type | GenericArgsConst | GenericArgsBinding | GenericArgsBounds
GenericArgsConst ->
BlockExpression
| LiteralExpression
| `-` LiteralExpression
| SimplePathSegment
GenericArgsBinding ->
IDENTIFIER GenericArgs? `=` Type
GenericArgsBounds ->
IDENTIFIER GenericArgs? `:` TypeParamBounds
```
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 | TypePathFn))?
TypePathFn -> `(` TypePathFnInputs? `)` (`->` TypeNoBounds)?
TypePathFnInputs -> Type (`,` Type)* `,`?
```
r[paths.type.intro]
Type paths are used within type definitions, trait bounds, type parameter 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
Paths can be denoted with various leading qualifiers to change the meaning of
how it is resolved.
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` can only be used as the first segment, without a preceding `::`.
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]
Items defined in a module or implementation have 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
[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
[value namespace]: names/namespaces.md
[visibility]: visibility-and-privacy.md