Caution

You’re reading a draft of the Ferrocene Language Specification. Some parts of this document might be missing, incomplete or incorrect. Our aim is to have the specification ready by the end of 2022.

14. Entities and Resolution

14.1. Entities

Syntax

Name ::=
    Identifier

Legality Rules

14.1:1 An entity is a construct that can be referred to within program text, usually via a field access expression or a path.

14.1:2 A name is an identifier that refers to an entity.

14.1:3 A declaration is a construct that introduces a name for an entity.

14.1:4 An explicitly declared entity is an entity that has a declaration. The following entities are explicitly declared entities:

14.1:22 An implicitly declared entity is an entity that lacks an explicit declaration. The following entities are implicitly declared entities:

14.2. Visibility

Syntax

VisibilityModifier ::=
    CratePublicModifier
  | SelfPublicModifier
  | SimplePathPublicModifier
  | SimplePublicModifier
  | SuperPublicModifier

CratePublicModifier ::=
    pub ( crate )

SelfPublicModifier ::=
    pub ( self )

SimplePathPublicModifier ::=
    pub ( in SimplePath )

SimplePublicModifier ::=
    pub

SuperPublicModifier ::=
    pub ( super )

Legality Rules

14.2:1 Visibility is a property of fields and items that determines which modules can refer to the name of the field or item.

14.2:2 Public visibility is a kind of visibility that allows for a name to be referred to from arbitrary module M as long as the ancestor modules of the related entity can be referred to from M.

14.2:3 Private visibility is a kind of visibility that allows a name to be referred to only by the current module of the entity, and its descendant modules.

14.2:4 A visibility modifier sets the visibility of a name.

14.2:5 A crate public modifier is a visibility modifier that grants a name public visibility within the current crate only.

14.2:6 A self public modifier is a visibility modifier that grants a name private visibility. A self public modifier is equivalent to a simple path public modifier where the simple path denotes keyword self.

14.2:7 A simple path public modifier is a visibility modifier that grants a name public visibility within the provided simple path only.

14.2:8 The simple path of a simple path public modifier shall start with a path segment expressed by either keyword crate, keyword self, or keyword super.

14.2:9 The simple path of a simple path public modifier shall resolve to an ancestor module of the current module or the current module itself.

14.2:10 A simple public modifier is a visibility modifier that grants a name public visibility.

14.2:11 A super public modifier is a visibility modifier that grants a name public visibility within the parent module only. A super public modifier is equivalent to a simple path public modifier where the simple path denotes keyword super.

14.2:12 An external item, a field, or an item that appears without a visibility modifier has private visibility by default.

14.2:13 An associated item of a trait has the same visibility as the trait.

14.2:14 An enum variant and its fields have the same visibility as the containing enum type.

Examples

pub mod outer_module {
    pub mod inner_module {
        pub(crate) fn crate_visible_function() {}

        pub(self) fn inner_module_visible_function() {}

        pub(super) fn outer_module_visible_function() {}

        pub fn visible_function() {}

        fn caller() {
            crate_visible_function();
            inner_module_visible_function();
            visible_function();
        }
    }

    fn caller() {
        inner_module::crate_visible_function();
        inner_module::outer_module_visible_function();
        inner_module::visible_function();
    }
}

fn caller() {
    outer_module::inner_module::crate_visible_function();
    outer_module::inner_module::visible_function();
}

14.3. Paths

Syntax

SimplePath ::=
    ::? SimplePathSegment (:: SimplePathSegment)*

SimplePathSegment ::=
    Identifier
  | crate
  | $crate
  | self
  | super

SimplePathList ::=
    SimplePath (, SimplePath)* ,?

QualifiedType ::=
    < TypeSpecification QualifyingTrait? >

QualifyingTrait ::=
    as TypePath

PathExpression ::=
    ::? PathExpressionSegment (:: PathExpressionSegment)*

PathExpressionSegment ::=
    PathSegment (:: GenericArgumentList)?

PathSegment ::=
    SimplePathSegment
  | Self

QualifiedPathExpression ::=
    QualifiedType (:: PathExpressionSegment)+

TypePath ::=
    ::? TypePathSegment (:: TypePathSegment)*

TypePathSegment ::=
    PathSegment ::? (GenericArgumentList | QualifiedFnTrait)?

QualifiedFnTrait ::=
    ( TypeSpecificationList? ) ReturnType?

QualifiedTypePath ::=
    QualifiedType (:: TypePathSegment)+

Legality Rules

14.3:1 A path is a sequence of path segments logically separated by namespace qualifier :: that resolves to an entity.

14.3:2 A path segment is an element of a path.

14.3:3 A path is subject to path resolution.

14.3:4 If a path segment is expressed as either keyword crate, keyword $crate, keyword self, or keyword Self, then the path segment shall be the first path segment of a path.

14.3:5 A path that starts with a path segment that is expressed as keyword $crate shall appear only within a macro transcriber.

14.3:6 If a path segment is expressed as keyword super, then the path segment shall either be the first path segment of a path, or the previous path segment of the path shall also be expressed as keyword super.

14.3:7 A global path is a path that starts with namespace qualifier ::.

14.3:8 A simple path is a path whose path segments consist of either identifiers or certain keywords as defined in the syntax rules above.

14.3:9 If a simple path appears in a use import and starts with a path segment expressed as either keyword crate, keyword $crate, keyword self, or keyword super, then the path shall be the simple path prefix of a glob import or a nesting import, or the simple path of a simple import.

14.3:10 If a simple path appears in a use import and starts with a path segment expressed as keyword self, then the path shall be part of the UseImportContent of a nesting import as long as the path is a single segment path.

14.3:11 A simple path is subject to simple path resolution.

14.3:12 A single segment path is a path consisting of exactly one path segment.

14.3:13 A multi segment path is a path consisting of more than one path segment.

14.3:14 A path expression is a path that acts as an expression.

14.3:15 A path expression is subject to path expression resolution.

14.3:16 A type path is a path that acts as a type specification.

14.3:17 A type path is subject to type path resolution.

14.3:18 A qualifying trait is a trait that imposes a restriction on a qualified type.

14.3:19 A qualifying trait shall resolve to a trait.

14.3:20 A qualified type is a type that is restricted to a set of implementations that exhibit implementation conformance to a qualifying trait.

14.3:21 A qualified type shall resolve to a type.

14.3:22 A qualified type shall implement its related qualifying trait.

14.3:23 A qualified path expression is a path expression that resolves through a qualified type.

14.3:24 A qualified type path is a type path that resolves through a qualified type.

14.3:25 An associated type projection is a qualified type path of the form <type as trait>::associated_type, where type is a type, trait is a qualifying trait, and associated type is an associated type.

14.3:26 A qualified fn trait is a construct that refers to the core::ops::Fn, core::ops::FnMut, or core::ops::FnOnce trait.

14.3:27 If a path contains a path segment with a qualified fn trait, then the path segment shall be the last path segment of the path.

Examples

14.3:28 The following is a simple path. See Paragraph 14.2. for the declaration of crate_visible_function.

crate::outer_module::inner_module::crate_visible_function();

14.3:29 The following is a path expression with a generic argument.

Vec::<u8>::with_capacity(42);

14.3:30 The following is a type path with a generic argument.

std::boxed::Box<dyn std::ops::FnOnce(isize) -> size>;

struct S;
impl S {
    fn f() { println!("f of S"); }
}
trait T {
    fn f() { println!("f of T"); }
}
impl T for S {}

14.3:31 The following is a qualified type path (isn’t it a qualified path expression?). The call expression invokes T’s function.

<S as T>::f();

14.3:32 Add an example for qualified path expression.

14.4. Scopes

Legality Rules

14.4:1 A scope is a region of program text where an entity can be referred to. An entity is in scope when it can be referred to.

14.4.1. Binding Scopes

Legality Rules

14.4.1:1 A binding scope is a scope for bindings.

14.4.1:2 The binding of a closure parameter is in scope within the related closure body.

14.4.1:3 The binding of a function parameter is in scope within the related function body.

14.4.1:4 The binding of a for loop or a while let loop is in scope within the related loop body.

14.4.1:5 The binding of an if let expression is in scope within the related block expression.

14.4.1:6 The binding of a let statement is in scope after the related let statement, until the end of the block expression where the related let statement appears.

14.4.1:7 The binding of a match arm is in scope within its related expressions and related match arm guard.

14.4.2. Generic Parameter Scope

Legality Rules

14.4.2:1 A generic parameter scope is a scope for generic parameters.

14.4.2:2 A generic parameter is in scope of a GenericParameterList.

14.4.2:3 A generic parameter of an enum type is in scope within the related enum variants and where clause.

14.4.2:4 A generic parameter of a function pointer type is in scope within the related type specification.

14.4.2:5 A generic parameter of an implementation is in scope within the related implementation body and where clause.

14.4.2:6 A generic parameter of a struct type is in scope within the related fields and where clause.

14.4.2:7 A generic parameter of a trait is in scope within the related trait body and where clause.

14.4.2:8 A generic parameter of a trait bound is in scope within the related generic parameters or the related type path.

14.4.2:9 A generic parameter of a type alias is in scope within the related initialization type and where clause.

14.4.2:10 A generic parameter of a type bound predicate is in scope within the related TypeBoundList.

14.4.2:11 A generic parameter of a union type is in scope within the related fields and where clause.

14.4.2:12 A generic parameter is not in scope within nested items, except within associated items.

14.4.3. Item Scope

Legality Rules

14.4.3:1 An item scope is a scope for items.

14.4.3:2 An item declared within the block expression of an expression-with-block is in scope within the related block expression.

14.4.3:3 An item declared within a module is in scope within the related module. Such an item is not in scope within nested modules.

14.4.4. Label Scope

Legality Rules

14.4.4:1 A label scope is a scope for labels.

14.4.4:2 A label is in scope within the block expression of the related loop expression.

14.4.4:3 A label is not in scope within nested async blocks, closure expressions, constant contexts, and items.

14.4.5. Self Scope

Legality Rules

14.4.5:1 A Self scope is a scope for Self.

14.4.5:2 Self of an enum type is in scope within the related enum variants, generic parameters, and where clause.

14.4.5:3 Self of an implementation is in scope within the related generic parameters, implementation body, and where clause.

14.4.5:4 Self of a struct type is in scope within the related fields, generic parameters, and where clause.

14.4.5:5 Self of a trait is in scope within the related generic parameters, trait body, and where clause.

14.4.5:6 Self of a union type is in scope within the related fields, generic parameters, and where clause.

14.4.5:7 Self is not in scope within attributes.

14.4.6. Textual Macro Scope

Legality Rules

14.4.6:1 A textual macro scope is a scope for declarative macros.

14.4.6:2 A declarative macro is in scope after the related macro declaration, until the end of the block expression or the enclosing module where the macro declaration appears.

14.4.6:3 If the textual macro scope is introduced by a module and the module is subject to attribute macro_use, then the textual macro scope extends until the end of the scope introduced by the enclosing block expression or module.

14.4.7. Scope Hierarchy

Legality Rules

14.4.7:1 The scope hierarchy reflects the nesting of scopes as introduced by scoping constructs. An inner scope introduced by a nested scoping construct is the child of an outer scope introduced by an enclosing scoping construct.

14.4.7:2 A scoping construct is a construct that introduces scopes into the scope hierarchy. The following constructs are scoping constructs:

14.4.7:21 A closure expression introduces a binding scope into the scope hierarchy.

14.4.7:22 A declarative macro introduces a textual macro scope into the scope hierarchy.

14.4.7:23 The declaration of an enum type introduces a generic parameter scope and a Self scope into the scope hierarchy.

14.4.7:24 The declaration of a function introduces a binding scope and a generic parameter scope into the scope hierarchy.

14.4.7:25 The type specification of a function pointer type introduces a generic parameter scope into the scope hierarchy.

14.4.7:26 An if let expression introduces a binding scope into the scope hierarchy.

14.4.7:27 The declaration of an implementation introduces a generic parameter scope and a Self scope into the scope hierarchy.

14.4.7:28 A let statement introduces a binding scope into the scope hierarchy.

14.4.7:29 A for loop expression or a while let loop expression introduces a binding scope and a label scope into the scope hierarchy.

14.4.7:30 An infinite loop expression or a while loop expression introduces a label scope into the scope hierarchy.

14.4.7:31 A match arm introduces a binding scope into the scope hierarchy.

14.4.7:32 The declaration of a module introduces an item scope into the scope hierarchy.

14.4.7:33 The declaration of a struct type introduces a generic parameter scope and a Self scope into the scope hierarchy.

14.4.7:34 The declaration of a trait introduces a generic parameter scope and a Self scope into the scope hierarchy.

14.4.7:35 A trait bound introduces a generic parameter scope into the scope hierarchy.

14.4.7:36 The declaration of a type alias introduces a generic parameter scope.

14.4.7:37 A type bound predicate introduces a generic parameter scope into the scope hierarchy.

14.4.7:38 The declaration of a union type introduces a generic parameter scope and a Self scope into the scope hierarchy.

14.5. Namespaces

Legality Rules

14.5:1 A namespace is a logical grouping of names such that the occurrence of a name in one namespace does not conflict with an occurrence of the same name in another namespace.

14.5:2 Names are segregated into one of five namespaces based on the kind of entity the name refers to.

14.5:3 A label namespace contains labels.

14.5:4 A lifetime namespace contains the names of lifetime parameters.

14.5:5 A macro namespace contains the names of the following kinds of entities:

14.5:11 A type namespace contains the names of the following kinds of entities:

14.5:25 A value namespace contains the names of the following kinds of entities:

14.5:36 The names of the following kinds of entities are not part of any namespace:

14.6. Preludes

Legality Rules

14.6:1 A prelude is a collection of entities that are automatically brought in scope of every module in a crate. Such entities are referred to as prelude entities. The name of a prelude entity is referred to as a prelude name.

14.6:2 The core prelude is a prelude that brings in scope of every module all re-exported entities from the core::prelude::rust_2021 module.

14.6:3 An external prelude is a prelude that brings in scope of the crate root module the entities of the crates imported using external crate imports. If the external crate import uses a renaming, then the renaming is instead added to the external prelude. The core crate is always added to the external prelude unless the crate root is subject to attribute no_core.

14.6:4 The language prelude is a prelude that brings in scope of every module the following entities:

14.6:10 The macro_use prelude is a prelude that brings in scope of the crate root module the entities of macros from external crates that were imported using an external crate import.

14.7. Use Imports

Syntax

UseImport ::=
    use UseImportContent ;

UseImportContent ::=
    GlobImport
  | NestingImport
  | SimpleImport

GlobImport ::=
    SimplePathPrefix? *

NestingImport ::=
    SimplePathPrefix? { UseImportContentList? }

SimpleImport ::=
    SimplePath Renaming?

SimplePathPrefix ::=
    SimplePath? ::

UseImportContentList ::=
    UseImportContent (, UseImportContent)* ,?

Legality Rules

14.7:1 A use import brings entities in scope within the block expression of an expression-with-block or module where the use import resides.

14.7:2 A simple path prefix is the leading simple path of a glob import or a nesting import.

14.7:3 A glob import is a use import that brings all entities with public visibility prefixed by its simple path prefix into scope.

14.7:4 A nesting import is a use import that provides a common simple path prefix for its nested use imports.

14.7:5 A simple import is a use import that binds a simple path to a local name by using an optional renaming.

14.7:6 use self as foo -> imports the current module under the name “foo”

14.7:7 use blah::{self} -> imports “blah”

14.7:8 use blah::{self as foo} -> imports blah under the name “foo”

14.7:9 use blah::gah::{self} -> imports “gah”

14.7:10 use blah::{gah::{self as foo}} -> imports gah under the name “foo”

14.7:11 The above imports the names in the type namespace only

Examples

14.7:12 The following is a glob import. See Paragraph 14.2. for the declaration of modules and functions. The imported functions are create_visible_function, outer_module_visible_function, visible_function.

use outer_module::inner_module::*;

14.7:13 The following is a renaming import. The imported function is visible_function under the name f.

use outer_module::inner_module::visible_function as f;

14.7:14 The following is a selective import. The imported functions are crate_visible_function and visible_function.

use outer_module::inner_module
    {crate_visible_function, visible_function}

Legality Rules

14.8. Shadowing

Legality Rules

14.8:1 Shadowing is a property of names. A name is said to be shadowed when another name with the same characters is introduced in the same scope within the same namespace, effectively hiding it. A name cannot be referred to by any means once it is shadowed.

14.8:2 No name shall be shadowed except for

14.8:6 (this needs to mention about builtin type and module collisions, builtin attribute and macro collisions)

14.8:7 A prelude name shadows other prelude names depending on which preludes are included in a module. The order of shadowing is as follows, where a later prelude name shadows earlier prelude name:

  1. 14.8:8 Language prelude names.

  2. 14.8:9 Standard library prelude names.

  3. 14.8:10 macro_use prelude names.

  4. 14.8:11 Tool prelude names.

  5. 14.8:12 External prelude names.

14.9. Resolution

Legality Rules

14.9:1 Resolution is the process of finding a unique interpretation for a field access expression, a method call expression, or a path.

14.9:2 A construct that is being resolved is said to be under resolution.

14.9:3 A dereference type is either a reference type or a type that implements the core::ops::Deref trait.

14.9:4 A dereference type chain is a sequence of dereference types. A dereference type chain with an initial dereference type. From then on, the dereference type chain continues as follows:

14.9.1. Field Resolution

Legality Rules

14.9.1:1 Field resolution is a form of resolution that applies to a field access expression.

14.9.1:2 A candidate container type is the type of the container operand of a field access expression under resolution.

14.9.1:3 A candidate container type chain is a sequence of candidate container types. The candidate container type chain starts with the type of the container operand of the field access expression under resolution. From then on, the candidate container type chain is treated as a dereference type chain.

14.9.1:4 A candidate field is a field of a candidate container type that is visible from the location of the field access expression under resolution.

14.9.1:5 A candidate indexed field is a candidate field whose position in the type of the container operand matches the index of an indexed field selector.

14.9.1:6 A candidate named field is a candidate field whose name matches the characters of a named field selector.

14.9.1:7 Field resolution of a field access expression with an indexed field selector proceeds as follows:

  1. 14.9.1:8 For each candidate container type of the candidate container type chain

    1. 14.9.1:9 Try to locate a candidate indexed field of the candidate container type.

    2. 14.9.1:10 If such a candidate indexed field exists and is visible at the point of the field access expression, then the field access expression resolves to that candidate indexed field and field resolution stops.

14.9.1:11 Field resolution of a field access expression with a named field selector proceeds as follows:

  1. 14.9.1:12 For each candidate container type of the candidate container type chain

    1. 14.9.1:13 Try to locate a candidate named field of the candidate container type.

    2. 14.9.1:14 If such a candidate named field exists and is visible at the point of the field access expression, then the field access expression resolves to that candidate named field and field resolution stops.

14.9.1:15 A field access expression shall resolve to exactly one field.

14.9.2. Method Resolution

Legality Rules

14.9.2:1 Method resolution is a kind of resolution that applies to a method call expression.

14.9.2:2 A candidate receiver type is the type of the receiver operand of a method call expression under resolution.

14.9.2:3 A candidate receiver type chain is a sequence of candidate receiver types. The candidate receiver type chain starts with the type of the receiver operand of the method call expression under resolution. From then on, the candidate receiver type chain is treated as a dereference type chain.

14.9.2:4 A candidate method is a method of a candidate receiver type that is visible from the location of the method call expression under resolution.

14.9.2:5 Method resolution proceeds as follows:

  1. 14.9.2:6 For each candidate receiver type of the candidate receiver type chain

    1. 14.9.2:7 Perform method resolution receiver candidate lookup for the candidate receiver type.

    2. 14.9.2:8 If the last candidate receiver type is an array type, then perform method resolution receiver candidate lookup for a slice type where the slice type has the same element type as the array type.

14.9.2:9 Method resolution receiver candidate lookup for a receiver type proceeds as follows:

  1. 14.9.2:10 Perform method resolution implementation candidate lookup for the receiver type.

  2. 14.9.2:11 Perform method resolution implementation candidate lookup for the immutable borrow of the receiver type.

  3. 14.9.2:12 Perform method resolution implementation candidate lookup for the mutable borrow of the receiver type.

14.9.2:13 Method resolution implementation candidate lookup for a receiver type proceeds as follows:

  1. 14.9.2:14 Perform method resolution inherent implementation candidate lookup for the receiver type.

  2. 14.9.2:15 Perform method resolution trait implementation candidate lookup for the receiver type.

14.9.2:16 Method resolution inherent implementation candidate lookup for a receiver type proceeds as follows:

  1. 14.9.2:17 Construct the dereference type chain for the receiver type.

  2. 14.9.2:18 For each dereference type in the dereference type chain

    1. 14.9.2:19 For each inherent implementation in the set of inherent implementations of the dereference type where the implementing type unifies with the dereference type

      1. 14.9.2:20 Try to locate a candidate method in the inherent implementation, where the type of the self parameter unifies with the receiver type.

      2. 14.9.2:21 If such a candidate method exists, then the method call expression resolves to that candidate method and method resolution stops.

14.9.2:22 Method resolution trait implementation candidate lookup for a receiver type proceeds as follows:

  1. 14.9.2:23 Construct the dereference type chain for the receiver type.

  2. 14.9.2:24 For each dereference type in the dereference type chain

    1. 14.9.2:25 For each trait implementation of the dereference type where the implemented trait is in scope

      1. 14.9.2:26 Try to locate a candidate method in the trait implementation, where the type of the self parameter unifies with the receiver type.

      2. 14.9.2:27 If such a candidate method exists, then the method call expression resolves to that candidate method and method resolution stops.

14.9.2:28 A method call expression shall resolve to exactly one method.

14.9.3. Path Resolution

Legality Rules

14.9.3:1 Path resolution is a form of resolution that applies to a path.

14.9.3:2 Path resolution resolves a path by resolving individual path segments in sequence, starting from the leftmost path segment.

14.9.3:3 A path segment shall resolve to exactly one entity.

14.9.3:4 A candidate direct entity is an entity that is visible from the location of a path under resolution and is located by first examining textual macro scopes, followed by examining the scope hierarchy from the innermost scope enclosing the path to the outermost scope, followed by examining preludes.

14.9.3:5 A candidate external prelude entity is an entity that is visible from the location of a path under resolution and is located by examining the external prelude.

14.9.3:6 A candidate selected entity is an entity that is visible from the location of a path under resolution and is located within a resolution context.

14.9.3:7 A namespace context is a set of namespaces where the names of candidate selected entities reside.

14.9.3:8 A resolution context is a set of entities that informs path resolution by restricting the number of candidate selected entities.

14.9.3:9 The resolution of the leftmost path segment of a path proceeds as follows:

14.9.3:25 The resolution of the rightmost path segment is determined based on the path resolution kind, where the name of the candidate selected entity is restricted by the namespace context.

14.9.3.1. Simple Path Resolution

Legality Rules

14.9.3.1:1 Simple path resolution is a kind of path resolution that applies to a simple path.

14.9.3.1:2 The namespace context of simple path resolution is determined as follows:

14.9.3.1:6 The leftmost path segment of a simple path is resolved using general path resolution. The remaining path segments are resolved in left-to-right order, as follows:

14.9.3.2. Path Expression Resolution

Legality Rules

14.9.3.2:1 Path expression resolution is a form of path resolution that applies to a path expression.

14.9.3.2:2 The namespace context of path expression resolution is the value namespace.

14.9.3.2:3 The leftmost path segment of a path expression is resolved using general path resolution. The remaining path segments are resolved in left-to-right order, as follows:

14.9.3.2:13 Path expression resolution implementation candidate lookup for a path segment and a trait or type proceeds as follows:

  1. 14.9.3.2:14 Perform path expression resolution inherent implementation candidate lookup for the path segment and the trait or type.

  2. 14.9.3.2:15 Perform path expression resolution trait implementation candidate lookup for the path segment and the trait or type.

14.9.3.2:16 Path expression resolution inherent implementation candidate lookup for a path segment and a trait or type proceeds as follows:

  1. 14.9.3.2:17 For each inherent implementation in the set of inherent implementations of the trait or type where the implementing type unifies with the trait or type

    1. 14.9.3.2:18 Try to locate a visible constant or a visible function in the inherent implementation whose name matches the characters of the path segment.

    2. 14.9.3.2:19 If such a constant or function exists, then the path segment resolves to that constant or function and path expression resolution stops.

14.9.3.2:20 Path expression resolution trait implementation candidate lookup for a path segment and a trait or type proceeds as follows:

  1. 14.9.3.2:21 For each trait implementation of the trait or type where the implemented trait is in scope

    1. 14.9.3.2:22 Try to locate a visible constant or a visible function in the trait implementation whose name matches the characters of the path segment.

    2. 14.9.3.2:23 If such a constant or function exists, then the path segment resolves to that constant or function and path expression resolution stops.

14.9.3.3. Type Path Resolution

Legality Rules

14.9.3.3:1 Type path resolution is a form of path resolution that applies to a type path.

14.9.3.3:2 The namespace context of type path resolution is the type namespace.

14.9.3.3:3 The leftmost path segment of a type path is resolved using general path resolution. The remaining path segments are resolved in left-to-right order, as follows: