fn visit_scopes<T>(
        &mut self,
        scope_set: ScopeSet,
        parent_scope: &ParentScope<'a>,
        ident: Ident,
        mut visitor: impl FnMut(&mut Self, Scope<'a>, /*use_prelude*/ bool, Ident) -> Option<T>,
    ) -> Option<T> {
        // General principles:
        // 1. Not controlled (user-defined) names should have higher priority than controlled names
        //    built into the language or standard library. This way we can add new names into the
        //    language or standard library without breaking user code.
        // 2. "Closed set" below means new names cannot appear after the current resolution attempt.
        // Places to search (in order of decreasing priority):
        // (Type NS)
        // 1. FIXME: Ribs (type parameters), there's no necessary infrastructure yet
        //    (open set, not controlled).
        // 2. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents
        //    (open, not controlled).
        // 3. Extern prelude (open, the open part is from macro expansions, not controlled).
        // 4. Tool modules (closed, controlled right now, but not in the future).
        // 5. Standard library prelude (de-facto closed, controlled).
        // 6. Language prelude (closed, controlled).
        // (Value NS)
        // 1. FIXME: Ribs (local variables), there's no necessary infrastructure yet
        //    (open set, not controlled).
        // 2. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents
        //    (open, not controlled).
        // 3. Standard library prelude (de-facto closed, controlled).
        // (Macro NS)
        // 1-3. Derive helpers (open, not controlled). All ambiguities with other names
        //    are currently reported as errors. They should be higher in priority than preludes
        //    and probably even names in modules according to the "general principles" above. They
        //    also should be subject to restricted shadowing because are effectively produced by
        //    derives (you need to resolve the derive first to add helpers into scope), but they
        //    should be available before the derive is expanded for compatibility.
        //    It's mess in general, so we are being conservative for now.
        // 1-3. `macro_rules` (open, not controlled), loop through `macro_rules` scopes. Have higher
        //    priority than prelude macros, but create ambiguities with macros in modules.
        // 1-3. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents
        //    (open, not controlled). Have higher priority than prelude macros, but create
        //    ambiguities with `macro_rules`.
        // 4. `macro_use` prelude (open, the open part is from macro expansions, not controlled).
        // 4a. User-defined prelude from macro-use
        //    (open, the open part is from macro expansions, not controlled).
        // 4b. "Standard library prelude" part implemented through `macro-use` (closed, controlled).
        // 4c. Standard library prelude (de-facto closed, controlled).
        // 6. Language prelude: builtin attributes (closed, controlled).

        let rust_2015 = ident.span.rust_2015();
        let (ns, macro_kind, is_absolute_path) = match scope_set {
            ScopeSet::All(ns, _) => (ns, None, false),
            ScopeSet::AbsolutePath(ns) => (ns, None, true),
            ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind), false),
        };
        // Jump out of trait or enum modules, they do not act as scopes.
        let module = parent_scope.module.nearest_item_scope();
        let mut scope = match ns {
            _ if is_absolute_path => Scope::CrateRoot,
            TypeNS | ValueNS => Scope::Module(module),
            MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
        };
        let mut ident = ident.normalize_to_macros_2_0();
        let mut use_prelude = !module.no_implicit_prelude;

        loop {
            let visit = match scope {
                // Derive helpers are not in scope when resolving derives in the same container.
                Scope::DeriveHelpers(expn_id) => {
                    !(expn_id == parent_scope.expansion && macro_kind == Some(MacroKind::Derive))
                }
                Scope::DeriveHelpersCompat => true,
                Scope::MacroRules(..) => true,
                Scope::CrateRoot => true,
                Scope::Module(..) => true,
                Scope::RegisteredAttrs => use_prelude,
                Scope::MacroUsePrelude => use_prelude || rust_2015,
                Scope::BuiltinAttrs => true,
                Scope::ExternPrelude => use_prelude || is_absolute_path,
                Scope::ToolPrelude => use_prelude,
                Scope::StdLibPrelude => use_prelude || ns == MacroNS,
                Scope::BuiltinTypes => true,
            };

            if visit {
                if let break_result @ Some(..) = visitor(self, scope, use_prelude, ident) {
                    return break_result;
                }
            }

            scope = match scope {
                Scope::DeriveHelpers(expn_id) if expn_id != ExpnId::root() => {
                    // Derive helpers are not visible to code generated by bang or derive macros.
                    let expn_data = expn_id.expn_data();
                    match expn_data.kind {
                        ExpnKind::Root
                        | ExpnKind::Macro(MacroKind::Bang | MacroKind::Derive, _) => {
                            Scope::DeriveHelpersCompat
                        }
                        _ => Scope::DeriveHelpers(expn_data.parent),
                    }
                }
                Scope::DeriveHelpers(..) => Scope::DeriveHelpersCompat,
                Scope::DeriveHelpersCompat => Scope::MacroRules(parent_scope.macro_rules),
                Scope::MacroRules(macro_rules_scope) => match macro_rules_scope {
                    MacroRulesScope::Binding(binding) => {
                        Scope::MacroRules(binding.parent_macro_rules_scope)
                    }
                    MacroRulesScope::Invocation(invoc_id) => Scope::MacroRules(
                        self.output_macro_rules_scopes
                            .get(&invoc_id)
                            .cloned()
                            .unwrap_or(self.invocation_parent_scopes[&invoc_id].macro_rules),
                    ),
                    MacroRulesScope::Empty => Scope::Module(module),
                },
                Scope::CrateRoot => match ns {
                    TypeNS => {
                        ident.span.adjust(ExpnId::root());
                        Scope::ExternPrelude
                    }
                    ValueNS | MacroNS => break,
                },
                Scope::Module(module) => {
                    use_prelude = !module.no_implicit_prelude;
                    match self.hygienic_lexical_parent(module, &mut ident.span) {
                        Some(parent_module) => Scope::Module(parent_module),
                        None => {
                            ident.span.adjust(ExpnId::root());
                            match ns {
                                TypeNS => Scope::ExternPrelude,
                                ValueNS => Scope::StdLibPrelude,
                                MacroNS => Scope::RegisteredAttrs,
                            }
                        }
                    }
                }
                Scope::RegisteredAttrs => Scope::MacroUsePrelude,
                Scope::MacroUsePrelude => Scope::StdLibPrelude,
                Scope::BuiltinAttrs => break, // nowhere else to search
                Scope::ExternPrelude if is_absolute_path => break,
                Scope::ExternPrelude => Scope::ToolPrelude,
                Scope::ToolPrelude => Scope::StdLibPrelude,
                Scope::StdLibPrelude => match ns {
                    TypeNS => Scope::BuiltinTypes,
                    ValueNS => break, // nowhere else to search
                    MacroNS => Scope::BuiltinAttrs,
                },
                Scope::BuiltinTypes => break, // nowhere else to search
            };
        }

        None
    }
/// A generic scope visitor.
/// Visits scopes in order to resolve some identifier in them or perform other actions.
/// If the callback returns `Some` result, we stop visiting scopes and return it.
A generic scope visitor.
Visits scopes in order to resolve some identifier in them or perform other actions.
If the callback returns `Some` result, we stop visiting scopes and return it.
A generic scope visitor . Visits scopes in order to resolve some identifier in them or perform other actions . If the callback returns ` Some ` result we stop visiting scopes and return it .
fn visit_scopes<T>(
        &mut self,
        scope_set: ScopeSet,
        parent_scope: &ParentScope<'a>,
        ident: Ident,
        mut visitor: impl FnMut(&mut Self, Scope<'a>, /*use_prelude*/ bool, Ident) -> Option<T>,
    ) -> Option<T> {
        // General principles:
        // 1. Not controlled (user-defined) names should have higher priority than controlled names
        //    built into the language or standard library. This way we can add new names into the
        //    language or standard library without breaking user code.
        // 2. "Closed set" below means new names cannot appear after the current resolution attempt.
        // Places to search (in order of decreasing priority):
        // (Type NS)
        // 1. FIXME: Ribs (type parameters), there's no necessary infrastructure yet
        //    (open set, not controlled).
        // 2. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents
        //    (open, not controlled).
        // 3. Extern prelude (open, the open part is from macro expansions, not controlled).
        // 4. Tool modules (closed, controlled right now, but not in the future).
        // 5. Standard library prelude (de-facto closed, controlled).
        // 6. Language prelude (closed, controlled).
        // (Value NS)
        // 1. FIXME: Ribs (local variables), there's no necessary infrastructure yet
        //    (open set, not controlled).
        // 2. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents
        //    (open, not controlled).
        // 3. Standard library prelude (de-facto closed, controlled).
        // (Macro NS)
        // 1-3. Derive helpers (open, not controlled). All ambiguities with other names
        //    are currently reported as errors. They should be higher in priority than preludes
        //    and probably even names in modules according to the "general principles" above. They
        //    also should be subject to restricted shadowing because are effectively produced by
        //    derives (you need to resolve the derive first to add helpers into scope), but they
        //    should be available before the derive is expanded for compatibility.
        //    It's mess in general, so we are being conservative for now.
        // 1-3. `macro_rules` (open, not controlled), loop through `macro_rules` scopes. Have higher
        //    priority than prelude macros, but create ambiguities with macros in modules.
        // 1-3. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents
        //    (open, not controlled). Have higher priority than prelude macros, but create
        //    ambiguities with `macro_rules`.
        // 4. `macro_use` prelude (open, the open part is from macro expansions, not controlled).
        // 4a. User-defined prelude from macro-use
        //    (open, the open part is from macro expansions, not controlled).
        // 4b. "Standard library prelude" part implemented through `macro-use` (closed, controlled).
        // 4c. Standard library prelude (de-facto closed, controlled).
        // 6. Language prelude: builtin attributes (closed, controlled).
        let rust_2015 = ident.span.rust_2015();
        let (ns, macro_kind, is_absolute_path) = match scope_set {
            ScopeSet::All(ns, _) => (ns, None, false),
            ScopeSet::AbsolutePath(ns) => (ns, None, true),
            ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind), false),
        };
        // Jump out of trait or enum modules, they do not act as scopes.
        let module = parent_scope.module.nearest_item_scope();
        let mut scope = match ns {
            _ if is_absolute_path => Scope::CrateRoot,
            TypeNS | ValueNS => Scope::Module(module),
            MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
        };
        let mut ident = ident.normalize_to_macros_2_0();
        let mut use_prelude = !module.no_implicit_prelude;
        loop {
            let visit = match scope {
                // Derive helpers are not in scope when resolving derives in the same container.
                Scope::DeriveHelpers(expn_id) => {
                    !(expn_id == parent_scope.expansion && macro_kind == Some(MacroKind::Derive))
                }
                Scope::DeriveHelpersCompat => true,
                Scope::MacroRules(..) => true,
                Scope::CrateRoot => true,
                Scope::Module(..) => true,
                Scope::RegisteredAttrs => use_prelude,
                Scope::MacroUsePrelude => use_prelude || rust_2015,
                Scope::BuiltinAttrs => true,
                Scope::ExternPrelude => use_prelude || is_absolute_path,
                Scope::ToolPrelude => use_prelude,
                Scope::StdLibPrelude => use_prelude || ns == MacroNS,
                Scope::BuiltinTypes => true,
            };
            if visit {
                if let break_result @ Some(..) = visitor(self, scope, use_prelude, ident) {
                    return break_result;
                }
            }
            scope = match scope {
                Scope::DeriveHelpers(expn_id) if expn_id != ExpnId::root() => {
                    // Derive helpers are not visible to code generated by bang or derive macros.
                    let expn_data = expn_id.expn_data();
                    match expn_data.kind {
                        ExpnKind::Root
                        | ExpnKind::Macro(MacroKind::Bang | MacroKind::Derive, _) => {
                            Scope::DeriveHelpersCompat
                        }
                        _ => Scope::DeriveHelpers(expn_data.parent),
                    }
                }
                Scope::DeriveHelpers(..) => Scope::DeriveHelpersCompat,
                Scope::DeriveHelpersCompat => Scope::MacroRules(parent_scope.macro_rules),
                Scope::MacroRules(macro_rules_scope) => match macro_rules_scope {
                    MacroRulesScope::Binding(binding) => {
                        Scope::MacroRules(binding.parent_macro_rules_scope)
                    }
                    MacroRulesScope::Invocation(invoc_id) => Scope::MacroRules(
                        self.output_macro_rules_scopes
                            .get(&invoc_id)
                            .cloned()
                            .unwrap_or(self.invocation_parent_scopes[&invoc_id].macro_rules),
                    ),
                    MacroRulesScope::Empty => Scope::Module(module),
                },
                Scope::CrateRoot => match ns {
                    TypeNS => {
                        ident.span.adjust(ExpnId::root());
                        Scope::ExternPrelude
                    }
                    ValueNS | MacroNS => break,
                },
                Scope::Module(module) => {
                    use_prelude = !module.no_implicit_prelude;
                    match self.hygienic_lexical_parent(module, &mut ident.span) {
                        Some(parent_module) => Scope::Module(parent_module),
                        None => {
                            ident.span.adjust(ExpnId::root());
                            match ns {
                                TypeNS => Scope::ExternPrelude,
                                ValueNS => Scope::StdLibPrelude,
                                MacroNS => Scope::RegisteredAttrs,
                            }
                        }
                    }
                }
                Scope::RegisteredAttrs => Scope::MacroUsePrelude,
                Scope::MacroUsePrelude => Scope::StdLibPrelude,
                Scope::BuiltinAttrs => break, // nowhere else to search
                Scope::ExternPrelude if is_absolute_path => break,
                Scope::ExternPrelude => Scope::ToolPrelude,
                Scope::ToolPrelude => Scope::StdLibPrelude,
                Scope::StdLibPrelude => match ns {
                    TypeNS => Scope::BuiltinTypes,
                    ValueNS => break, // nowhere else to search
                    MacroNS => Scope::BuiltinAttrs,
                },
                Scope::BuiltinTypes => break, // nowhere else to search
            };
        }
        None
    }
fn visit_scopes < T > ( & mut self , scope_set : ScopeSet , parent_scope : & ParentScope < ' a > , ident : Ident , mut visitor : impl FnMut ( & mut Self , Scope < ' a > , /*use_prelude*/ bool , Ident ) -> Option < T > , ) -> Option < T > { // General principles: // 1. Not controlled (user-defined) names should have higher priority than controlled names //    built into the language or standard library. This way we can add new names into the //    language or standard library without breaking user code. // 2. "Closed set" below means new names cannot appear after the current resolution attempt. // Places to search (in order of decreasing priority): // (Type NS) // 1. FIXME: Ribs (type parameters), there's no necessary infrastructure yet //    (open set, not controlled). // 2. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents //    (open, not controlled). // 3. Extern prelude (open, the open part is from macro expansions, not controlled). // 4. Tool modules (closed, controlled right now, but not in the future). // 5. Standard library prelude (de-facto closed, controlled). // 6. Language prelude (closed, controlled). // (Value NS) // 1. FIXME: Ribs (local variables), there's no necessary infrastructure yet //    (open set, not controlled). // 2. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents //    (open, not controlled). // 3. Standard library prelude (de-facto closed, controlled). // (Macro NS) // 1-3. Derive helpers (open, not controlled). All ambiguities with other names //    are currently reported as errors. They should be higher in priority than preludes //    and probably even names in modules according to the "general principles" above. They //    also should be subject to restricted shadowing because are effectively produced by //    derives (you need to resolve the derive first to add helpers into scope), but they //    should be available before the derive is expanded for compatibility. //    It's mess in general, so we are being conservative for now. // 1-3. `macro_rules` (open, not controlled), loop through `macro_rules` scopes. Have higher //    priority than prelude macros, but create ambiguities with macros in modules. // 1-3. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents //    (open, not controlled). Have higher priority than prelude macros, but create //    ambiguities with `macro_rules`. // 4. `macro_use` prelude (open, the open part is from macro expansions, not controlled). // 4a. User-defined prelude from macro-use //    (open, the open part is from macro expansions, not controlled). // 4b. "Standard library prelude" part implemented through `macro-use` (closed, controlled). // 4c. Standard library prelude (de-facto closed, controlled). // 6. Language prelude: builtin attributes (closed, controlled). let rust_2015 = ident . span . rust_2015 ( ) ; let ( ns , macro_kind , is_absolute_path ) = match scope_set { ScopeSet :: All ( ns , _ ) => ( ns , None , false ) , ScopeSet :: AbsolutePath ( ns ) => ( ns , None , true ) , ScopeSet :: Macro ( macro_kind ) => ( MacroNS , Some ( macro_kind ) , false ) , } ; // Jump out of trait or enum modules, they do not act as scopes. let module = parent_scope . module . nearest_item_scope ( ) ; let mut scope = match ns { _ if is_absolute_path => Scope :: CrateRoot , TypeNS | ValueNS => Scope :: Module ( module ) , MacroNS => Scope :: DeriveHelpers ( parent_scope . expansion ) , } ; let mut ident = ident . normalize_to_macros_2_0 ( ) ; let mut use_prelude = ! module . no_implicit_prelude ; loop { let visit = match scope { // Derive helpers are not in scope when resolving derives in the same container. Scope :: DeriveHelpers ( expn_id ) => { ! ( expn_id == parent_scope . expansion && macro_kind == Some ( MacroKind :: Derive ) ) } Scope :: DeriveHelpersCompat => true , Scope :: MacroRules ( .. ) => true , Scope :: CrateRoot => true , Scope :: Module ( .. ) => true , Scope :: RegisteredAttrs => use_prelude , Scope :: MacroUsePrelude => use_prelude || rust_2015 , Scope :: BuiltinAttrs => true , Scope :: ExternPrelude => use_prelude || is_absolute_path , Scope :: ToolPrelude => use_prelude , Scope :: StdLibPrelude => use_prelude || ns == MacroNS , Scope :: BuiltinTypes => true , } ; if visit { if let break_result @ Some ( .. ) = visitor ( self , scope , use_prelude , ident ) { return break_result ; } } scope = match scope { Scope :: DeriveHelpers ( expn_id ) if expn_id != ExpnId :: root ( ) => { // Derive helpers are not visible to code generated by bang or derive macros. let expn_data = expn_id . expn_data ( ) ; match expn_data . kind { ExpnKind :: Root | ExpnKind :: Macro ( MacroKind :: Bang | MacroKind :: Derive , _ ) => { Scope :: DeriveHelpersCompat } _ => Scope :: DeriveHelpers ( expn_data . parent ) , } } Scope :: DeriveHelpers ( .. ) => Scope :: DeriveHelpersCompat , Scope :: DeriveHelpersCompat => Scope :: MacroRules ( parent_scope . macro_rules ) , Scope :: MacroRules ( macro_rules_scope ) => match macro_rules_scope { MacroRulesScope :: Binding ( binding ) => { Scope :: MacroRules ( binding . parent_macro_rules_scope ) } MacroRulesScope :: Invocation ( invoc_id ) => Scope :: MacroRules ( self . output_macro_rules_scopes . get ( & invoc_id ) . cloned ( ) . unwrap_or ( self . invocation_parent_scopes [ & invoc_id ] . macro_rules ) , ) , MacroRulesScope :: Empty => Scope :: Module ( module ) , } , Scope :: CrateRoot => match ns { TypeNS => { ident . span . adjust ( ExpnId :: root ( ) ) ; Scope :: ExternPrelude } ValueNS | MacroNS => break , } , Scope :: Module ( module ) => { use_prelude = ! module . no_implicit_prelude ; match self . hygienic_lexical_parent ( module , & mut ident . span ) { Some ( parent_module ) => Scope :: Module ( parent_module ) , None => { ident . span . adjust ( ExpnId :: root ( ) ) ; match ns { TypeNS => Scope :: ExternPrelude , ValueNS => Scope :: StdLibPrelude , MacroNS => Scope :: RegisteredAttrs , } } } } Scope :: RegisteredAttrs => Scope :: MacroUsePrelude , Scope :: MacroUsePrelude => Scope :: StdLibPrelude , Scope :: BuiltinAttrs => break , // nowhere else to search Scope :: ExternPrelude if is_absolute_path => break , Scope :: ExternPrelude => Scope :: ToolPrelude , Scope :: ToolPrelude => Scope :: StdLibPrelude , Scope :: StdLibPrelude => match ns { TypeNS => Scope :: BuiltinTypes , ValueNS => break , // nowhere else to search MacroNS => Scope :: BuiltinAttrs , } , Scope :: BuiltinTypes => break , // nowhere else to search } ; } None }
A generic scope visitor.
A generic scope visitor .
&mut self
scope_set
ScopeSet
parent_scope
&ParentScope<'a>
ident
Ident
visitor
impl FnMut(&mut Self, Scope<'a>, /*use_prelude*/ bool, Ident) -> Option<T>
&mut self
scope_set
ScopeSet
parent_scope
&ParentScope<'a>
ident
Ident
visitor
impl FnMut(&mut Self, Scope<'a>, /*use_prelude*/ bool, Ident) -> Option<T>