blob: 2625903444c273e7d174e5ab28fd4c86cf946e4a [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]
> **<sup>Syntax</sup>**\
> _SimplePath_ :\
> &nbsp;&nbsp; `::`<sup>?</sup> _SimplePathSegment_ (`::` _SimplePathSegment_)<sup>\*</sup>
>
> _SimplePathSegment_ :\
> &nbsp;&nbsp; [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]
> **<sup>Syntax</sup>**\
> _PathInExpression_ :\
> &nbsp;&nbsp; `::`<sup>?</sup> _PathExprSegment_ (`::` _PathExprSegment_)<sup>\*</sup>
>
> _PathExprSegment_ :\
> &nbsp;&nbsp; _PathIdentSegment_ (`::` _GenericArgs_)<sup>?</sup>
>
> _PathIdentSegment_ :\
> &nbsp;&nbsp; [IDENTIFIER] | `super` | `self` | `Self` | `crate` | `$crate`
>
> _GenericArgs_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; `<` `>`\
> &nbsp;&nbsp; | `<` ( _GenericArg_ `,` )<sup>\*</sup> _GenericArg_ `,`<sup>?</sup> `>`
>
> _GenericArg_ :\
> &nbsp;&nbsp; [_Lifetime_] | [_Type_] | _GenericArgsConst_ | _GenericArgsBinding_ | _GenericArgsBounds_
>
> _GenericArgsConst_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; [_BlockExpression_]\
> &nbsp;&nbsp; | [_LiteralExpression_]\
> &nbsp;&nbsp; | `-` [_LiteralExpression_]\
> &nbsp;&nbsp; | [_SimplePathSegment_]
>
> _GenericArgsBinding_ :\
> &nbsp;&nbsp; [IDENTIFIER] _GenericArgs_<sup>?</sup> `=` [_Type_]
>
> _GenericArgsBounds_ :\
> &nbsp;&nbsp; [IDENTIFIER] _GenericArgs_<sup>?</sup> `:` [_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] or a single segment path.
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]
> **<sup>Syntax</sup>**\
> _QualifiedPathInExpression_ :\
> &nbsp;&nbsp; _QualifiedPathType_ (`::` _PathExprSegment_)<sup>+</sup>
>
> _QualifiedPathType_ :\
> &nbsp;&nbsp; `<` [_Type_] (`as` _TypePath_)<sup>?</sup> `>`
>
> _QualifiedPathInType_ :\
> &nbsp;&nbsp; _QualifiedPathType_ (`::` _TypePathSegment_)<sup>+</sup>
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]
> **<sup>Syntax</sup>**\
> _TypePath_ :\
> &nbsp;&nbsp; `::`<sup>?</sup> _TypePathSegment_ (`::` _TypePathSegment_)<sup>\*</sup>
>
> _TypePathSegment_ :\
> &nbsp;&nbsp; _PathIdentSegment_ (`::`<sup>?</sup> ([_GenericArgs_] | _TypePathFn_))<sup>?</sup>
>
> _TypePathFn_ :\
> `(` _TypePathFnInputs_<sup>?</sup> `)` (`->` [_TypeNoBounds_])<sup>?</sup>
>
> _TypePathFnInputs_ :\
> [_Type_] (`,` [_Type_])<sup>\*</sup> `,`<sup>?</sup>
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.edition2015]
> **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.
```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() {}
```
[_BlockExpression_]: expressions/block-expr.md
[_Expression_]: expressions.md
[_GenericArgs_]: #paths-in-expressions
[_Lifetime_]: trait-bounds.md
[_LiteralExpression_]: expressions/literal-expr.md
[_SimplePathSegment_]: #simple-paths
[_Type_]: types.md#type-expressions
[_TypeNoBounds_]: types.md#type-expressions
[_TypeParamBounds_]: trait-bounds.md
[implementations]: items/implementations.md
[items]: items.md
[literal]: expressions/literal-expr.md
[use declarations]: items/use-declarations.md
[IDENTIFIER]: identifiers.md
[`Self` scope]: names/scopes.md#self-scope
[`use`]: items/use-declarations.md
[attributes]: attributes.md
[enumeration]: items/enumerations.md
[expressions]: expressions.md
[extern prelude]: names/preludes.md#extern-prelude
[implementation]: items/implementations.md
[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