Scopes
A scope is the region of source text where a named entity may be referenced with that name. The following sections provide details on the scoping rules and behavior, which depend on the kind of entity and where it is declared. The process of how names are resolved to entities is described in the name resolution chapter. More information on “drop scopes” used for the purpose of running destructors may be found in the destructors chapter.
Item scopes
The name of an item declared directly in a module has a scope that extends from the start of the module to the end of the module. These items are also members of the module and can be referred to with a path leading from their module.
The name of an item declared as a statement has a scope that extends from the start of the block the item statement is in until the end of the block.
It is an error to introduce an item with a duplicate name of another item in the same namespace within the same module or block. Asterisk glob imports have special behavior for dealing with duplicate names and shadowing, see the linked chapter for more details. Items in a module may shadow items in a prelude.
Item names from outer modules are not in scope within a nested module. A path may be used to refer to an item in another module.
Associated item scopes
Associated items are not scoped and can only be referred to by using a path leading from the type or trait they are associated with. Methods can also be referred to via call expressions.
Similar to items within a module or block, it is an error to introduce an item within a trait or implementation that is a duplicate of another item in the trait or impl in the same namespace.
Pattern binding scopes
The scope of a local variable pattern binding depends on where it is used:
let
statement bindings range from just after thelet
statement until the end of the block where it is declared.- Function parameter bindings are within the body of the function.
- Closure parameter bindings are within the closure body.
for
andwhile let
bindings are within the loop body.if let
bindings are within the consequent block.match
arms bindings are within the match guard and the match arm expression.
Local variable scopes do not extend into item declarations.
Pattern binding shadowing
Pattern bindings are allowed to shadow any name in scope with the following exceptions which are an error:
- Const generic parameters
- Static items
- Const items
- Constructors for structs and enums
The following example illustrates how local bindings can shadow item declarations:
Generic parameter scopes
Generic parameters are declared in a GenericParams list. The scope of a generic parameter is within the item it is declared on.
All parameters are in scope within the generic parameter list regardless of the order they are declared. The following shows some examples where a parameter may be referenced before it is declared:
Generic parameters are also in scope for type bounds and where clauses, for example:
It is an error for items declared inside a function to refer to a generic parameter from their outer scope.
Generic parameter shadowing
It is an error to shadow a generic parameter with the exception that items declared within functions are allowed to shadow generic parameter names from the function.
Lifetime scopes
Lifetime parameters are declared in a GenericParams list and higher-ranked trait bounds.
The 'static
lifetime and placeholder lifetime '_
have a special meaning and cannot be declared as a parameter.
Lifetime generic parameter scopes
Constant and static items and const contexts only ever allow 'static
lifetime references, so no other lifetime may be in scope within them.
Associated consts do allow referring to lifetimes declared in their trait or implementation.
Higher-ranked trait bound scopes
The scope of a lifetime parameter declared as a higher-ranked trait bound depends on the scenario where it is used.
- As a TypeBoundWhereClauseItem the declared lifetimes are in scope in the type and the type bounds.
- As a TraitBound the declared lifetimes are in scope within the bound type path.
- As a BareFunctionType the declared lifetimes are in scope within the function parameters and return type.
Impl trait restrictions
Impl trait types can only reference lifetimes declared on a function or implementation.
Loop label scopes
Loop labels may be declared by a loop expression.
The scope of a loop label is from the point it is declared till the end of the loop expression.
The scope does not extend into items, closures, async blocks, const arguments, const contexts, and the iterator expression of the defining for
loop.
Loop labels may shadow labels of the same name in outer scopes. References to a label refer to the closest definition.
Prelude scopes
Preludes bring entities into scope of every module. The entities are not members of the module, but are implicitly queried during name resolution. The prelude names may be shadowed by declarations in a module.
The preludes are layered such that one shadows another if they contain entities of the same name. The order that preludes may shadow other preludes is the following where earlier entries may shadow later ones:
macro_rules
scopes
The scope of macro_rules
macros is described in the Macros By Example chapter.
The behavior depends on the use of the macro_use
and macro_export
attributes.
Derive macro helper attributes
Derive macro helper attributes are in scope in the item where their corresponding derive
attribute is specified.
The scope extends from just after the derive
attribute to the end of the item.
Helper attributes shadow other attributes of the same name in scope.
Self
scope
Although Self
is a keyword with special meaning, it interacts with name resolution in a way similar to normal names.
The implicit Self
type in the definition of a struct, enum, union, trait, or implementation is treated similarly to a generic parameter, and is in scope in the same way as a generic type parameter.
The implicit Self
constructor in the value namespace of an implementation is in scope within the body of the implementation (the implementation’s associated items).