compiler/rustc_resolve/src/ident.rs RUST 2,199 lines View on github.com → Search inside
File is large — showing lines 1–2,000 of 2,199.
1use std::ops::ControlFlow;23use Determinacy::*;4use Namespace::*;5use rustc_ast::{self as ast, NodeId};6use rustc_errors::ErrorGuaranteed;7use rustc_hir::def::{DefKind, MacroKinds, Namespace, NonMacroAttrKind, PartialRes, PerNS};8use rustc_lint_defs::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK;9use rustc_middle::{bug, span_bug};10use rustc_session::diagnostics::feature_err;11use rustc_span::edition::Edition;12use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext};13use rustc_span::{Ident, Span, kw, sym};14use smallvec::SmallVec;15use tracing::{debug, instrument};1617use crate::diagnostics::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};18use crate::hygiene::Macros20NormalizedSyntaxContext;19use crate::imports::{Import, NameResolution, cycle_detection};20use crate::late::{21    ConstantHasGenerics, DiagMetadata, NoConstantGenericsReason, PathSource, Rib, RibKind,22};23use crate::macros::{MacroRulesScope, sub_namespace_match};24use crate::{25    AmbiguityError, AmbiguityKind, AmbiguityWarning, BindingKey, CmResolver, Decl, DeclKind,26    Determinacy, ExternModule, Finalize, IdentKey, ImportKind, ImportSummary, LateDecl,27    LocalModule, Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError,28    Res, ResolutionError, Resolver, Scope, ScopeSet, Segment, Stage, Symbol, Used, diagnostics,29    module_to_string,30};3132#[derive(Copy, Clone)]33pub enum UsePrelude {34    No,35    Yes,36}3738impl From<UsePrelude> for bool {39    fn from(up: UsePrelude) -> bool {40        matches!(up, UsePrelude::Yes)41    }42}4344#[derive(Debug, PartialEq, Clone, Copy)]45enum Shadowing {46    Restricted,47    Unrestricted,48}4950impl<'ra, 'tcx> Resolver<'ra, 'tcx> {51    /// A generic scope visitor.52    /// Visits scopes in order to resolve some identifier in them or perform other actions.53    /// If the callback returns `Some` result, we stop visiting scopes and return it.54    pub(crate) fn visit_scopes<'r, T>(55        mut self: CmResolver<'r, 'ra, 'tcx>,56        scope_set: ScopeSet<'ra>,57        parent_scope: &ParentScope<'ra>,58        mut ctxt: Macros20NormalizedSyntaxContext,59        orig_ident_span: Span,60        derive_fallback_lint_id: Option<NodeId>,61        mut visitor: impl FnMut(62            CmResolver<'_, 'ra, 'tcx>,63            Scope<'ra>,64            UsePrelude,65            Macros20NormalizedSyntaxContext,66        ) -> ControlFlow<T>,67    ) -> Option<T> {68        // General principles:69        // 1. Not controlled (user-defined) names should have higher priority than controlled names70        //    built into the language or standard library. This way we can add new names into the71        //    language or standard library without breaking user code.72        // 2. "Closed set" below means new names cannot appear after the current resolution attempt.73        // Places to search (in order of decreasing priority):74        // (Type NS)75        // 1. FIXME: Ribs (type parameters), there's no necessary infrastructure yet76        //    (open set, not controlled).77        // 2. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents78        //    (open, not controlled).79        // 3. Extern prelude (open, the open part is from macro expansions, not controlled).80        // 4. Tool modules (closed, controlled right now, but not in the future).81        // 5. Standard library prelude (de-facto closed, controlled).82        // 6. Language prelude (closed, controlled).83        // (Value NS)84        // 1. FIXME: Ribs (local variables), there's no necessary infrastructure yet85        //    (open set, not controlled).86        // 2. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents87        //    (open, not controlled).88        // 3. Standard library prelude (de-facto closed, controlled).89        // (Macro NS)90        // 1-3. Derive helpers (open, not controlled). All ambiguities with other names91        //    are currently reported as errors. They should be higher in priority than preludes92        //    and probably even names in modules according to the "general principles" above. They93        //    also should be subject to restricted shadowing because are effectively produced by94        //    derives (you need to resolve the derive first to add helpers into scope), but they95        //    should be available before the derive is expanded for compatibility.96        //    It's mess in general, so we are being conservative for now.97        // 1-3. `macro_rules` (open, not controlled), loop through `macro_rules` scopes. Have higher98        //    priority than prelude macros, but create ambiguities with macros in modules.99        // 1-3. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents100        //    (open, not controlled). Have higher priority than prelude macros, but create101        //    ambiguities with `macro_rules`.102        // 4. `macro_use` prelude (open, the open part is from macro expansions, not controlled).103        // 4a. User-defined prelude from macro-use104        //    (open, the open part is from macro expansions, not controlled).105        // 4b. "Standard library prelude" part implemented through `macro-use` (closed, controlled).106        // 4c. Standard library prelude (de-facto closed, controlled).107        // 6. Language prelude: builtin attributes (closed, controlled).108109        let (ns, macro_kind) = match scope_set {110            ScopeSet::All(ns)111            | ScopeSet::Module(ns, _)112            | ScopeSet::ModuleAndExternPrelude(ns, _) => (ns, None),113            ScopeSet::ExternPrelude => (TypeNS, None),114            ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),115        };116        let module = match scope_set {117            // Start with the specified module.118            ScopeSet::Module(_, module) | ScopeSet::ModuleAndExternPrelude(_, module) => module,119            // Jump out of trait or enum modules, they do not act as scopes.120            _ => parent_scope.module.nearest_item_scope(),121        };122        let module_only = matches!(scope_set, ScopeSet::Module(..));123        let module_and_extern_prelude = matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..));124        let extern_prelude = matches!(scope_set, ScopeSet::ExternPrelude);125        let mut scope = match ns {126            _ if module_only || module_and_extern_prelude => Scope::ModuleNonGlobs(module, None),127            _ if extern_prelude => Scope::ExternPreludeItems,128            TypeNS | ValueNS => Scope::ModuleNonGlobs(module, None),129            MacroNS => Scope::DeriveHelpers(parent_scope.expansion),130        };131        let mut use_prelude = !module.no_implicit_prelude;132133        loop {134            let visit = match scope {135                // Derive helpers are not in scope when resolving derives in the same container.136                Scope::DeriveHelpers(expn_id) => {137                    !(expn_id == parent_scope.expansion && macro_kind == Some(MacroKind::Derive))138                }139                Scope::DeriveHelpersCompat => true,140                Scope::MacroRules(macro_rules_scope) => {141                    // Use "path compression" on `macro_rules` scope chains. This is an optimization142                    // used to avoid long scope chains, see the comments on `MacroRulesScopeRef`.143                    // As another consequence of this optimization visitors never observe invocation144                    // scopes for macros that were already expanded.145                    let mut scope = macro_rules_scope.get();146                    while let MacroRulesScope::Invocation(invoc_id) = scope {147                        if let Some(next) = self.output_macro_rules_scopes.get(&invoc_id) {148                            scope = next.get();149                            macro_rules_scope.set(scope);150                        } else {151                            break;152                        }153                    }154                    true155                }156                Scope::ModuleNonGlobs(..) | Scope::ModuleGlobs(..) => true,157                Scope::MacroUsePrelude => use_prelude || orig_ident_span.is_rust_2015(),158                Scope::BuiltinAttrs => true,159                Scope::ExternPreludeItems | Scope::ExternPreludeFlags => {160                    use_prelude || module_and_extern_prelude || extern_prelude161                }162                Scope::ToolAttributePrelude => use_prelude,163                Scope::StdLibPrelude => use_prelude || ns == MacroNS,164                Scope::BuiltinTypes => true,165            };166167            if visit {168                let use_prelude = if use_prelude { UsePrelude::Yes } else { UsePrelude::No };169                if let ControlFlow::Break(break_result) =170                    visitor(self.reborrow(), scope, use_prelude, ctxt)171                {172                    return Some(break_result);173                }174            }175176            scope = match scope {177                Scope::DeriveHelpers(LocalExpnId::ROOT) => Scope::DeriveHelpersCompat,178                Scope::DeriveHelpers(expn_id) => {179                    // Derive helpers are not visible to code generated by bang or derive macros.180                    let expn_data = expn_id.expn_data();181                    match expn_data.kind {182                        ExpnKind::Root183                        | ExpnKind::Macro(MacroKind::Bang | MacroKind::Derive, _) => {184                            Scope::DeriveHelpersCompat185                        }186                        _ => Scope::DeriveHelpers(expn_data.parent.expect_local()),187                    }188                }189                Scope::DeriveHelpersCompat => Scope::MacroRules(parent_scope.macro_rules),190                Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() {191                    MacroRulesScope::Def(binding) => {192                        Scope::MacroRules(binding.parent_macro_rules_scope)193                    }194                    MacroRulesScope::Invocation(invoc_id) => {195                        Scope::MacroRules(self.invocation_parent_scopes[&invoc_id].macro_rules)196                    }197                    MacroRulesScope::Empty => Scope::ModuleNonGlobs(module, None),198                },199                Scope::ModuleNonGlobs(module, lint_id) => Scope::ModuleGlobs(module, lint_id),200                Scope::ModuleGlobs(..) if module_only => break,201                Scope::ModuleGlobs(..) if module_and_extern_prelude => match ns {202                    TypeNS => {203                        ctxt.update_unchecked(|ctxt| ctxt.adjust(ExpnId::root()));204                        Scope::ExternPreludeItems205                    }206                    ValueNS | MacroNS => break,207                },208                Scope::ModuleGlobs(module, prev_lint_id) => {209                    use_prelude = !module.no_implicit_prelude;210                    match self.hygienic_lexical_parent(module, &mut ctxt, derive_fallback_lint_id) {211                        Some((parent_module, lint_id)) => {212                            Scope::ModuleNonGlobs(parent_module, lint_id.or(prev_lint_id))213                        }214                        None => {215                            ctxt.update_unchecked(|ctxt| ctxt.adjust(ExpnId::root()));216                            match ns {217                                TypeNS => Scope::ExternPreludeItems,218                                ValueNS => Scope::StdLibPrelude,219                                MacroNS => Scope::MacroUsePrelude,220                            }221                        }222                    }223                }224                Scope::MacroUsePrelude => Scope::StdLibPrelude,225                Scope::BuiltinAttrs => break, // nowhere else to search226                Scope::ExternPreludeItems => Scope::ExternPreludeFlags,227                Scope::ExternPreludeFlags if module_and_extern_prelude || extern_prelude => break,228                Scope::ExternPreludeFlags => Scope::ToolAttributePrelude,229                Scope::ToolAttributePrelude => Scope::StdLibPrelude,230                Scope::StdLibPrelude => match ns {231                    TypeNS => Scope::BuiltinTypes,232                    ValueNS => break, // nowhere else to search233                    MacroNS => Scope::BuiltinAttrs,234                },235                Scope::BuiltinTypes => break, // nowhere else to search236            };237        }238239        None240    }241242    fn hygienic_lexical_parent(243        &self,244        module: Module<'ra>,245        ctxt: &mut Macros20NormalizedSyntaxContext,246        derive_fallback_lint_id: Option<NodeId>,247    ) -> Option<(Module<'ra>, Option<NodeId>)> {248        if !module.expansion.outer_expn_is_descendant_of(**ctxt) {249            let expn_id = ctxt.update_unchecked(|ctxt| ctxt.remove_mark());250            return Some((self.expn_def_scope(expn_id), None));251        }252253        if let ModuleKind::Block = module.kind {254            return Some((module.parent.unwrap().nearest_item_scope(), None));255        }256257        // We need to support the next case under a deprecation warning258        // ```259        // struct MyStruct;260        // ---- begin: this comes from a proc macro derive261        // mod implementation_details {262        //     // Note that `MyStruct` is not in scope here.263        //     impl SomeTrait for MyStruct { ... }264        // }265        // ---- end266        // ```267        // So we have to fall back to the module's parent during lexical resolution in this case.268        if derive_fallback_lint_id.is_some()269            && let Some(parent) = module.parent270            // Inner module is inside the macro271            && module.expansion != parent.expansion272            // Parent module is outside of the macro273            && module.expansion.is_descendant_of(parent.expansion)274            // The macro is a proc macro derive275            && let Some(def_id) = module.expansion.expn_data().macro_def_id276        {277            let ext = self.get_macro_by_def_id(def_id);278            if ext.builtin_name.is_none()279                && ext.macro_kinds() == MacroKinds::DERIVE280                && parent.expansion.outer_expn_is_descendant_of(**ctxt)281            {282                return Some((parent, derive_fallback_lint_id));283            }284        }285286        None287    }288289    /// This resolves the identifier `ident` in the namespace `ns` in the current lexical scope.290    /// More specifically, we proceed up the hierarchy of scopes and return the binding for291    /// `ident` in the first scope that defines it (or None if no scopes define it).292    ///293    /// A block's items are above its local variables in the scope hierarchy, regardless of where294    /// the items are defined in the block. For example,295    /// ```rust296    /// fn f() {297    ///    g(); // Since there are no local variables in scope yet, this resolves to the item.298    ///    let g = || {};299    ///    fn g() {}300    ///    g(); // This resolves to the local variable `g` since it shadows the item.301    /// }302    /// ```303    ///304    /// Invariant: This must only be called during main resolution, not during305    /// import resolution.306    #[instrument(level = "debug", skip(self, ribs))]307    pub(crate) fn resolve_ident_in_lexical_scope(308        &mut self,309        mut ident: Ident,310        ns: Namespace,311        parent_scope: &ParentScope<'ra>,312        finalize: Option<Finalize>,313        ribs: &[Rib<'ra>],314        ignore_decl: Option<Decl<'ra>>,315        diag_metadata: Option<&DiagMetadata<'_>>,316    ) -> Option<LateDecl<'ra>> {317        let orig_ident = ident;318        let (general_span, normalized_span) = if ident.name == kw::SelfUpper {319            // FIXME(jseyfried) improve `Self` hygiene320            let empty_span = ident.span.with_ctxt(SyntaxContext::root());321            (empty_span, empty_span)322        } else if ns == TypeNS {323            let normalized_span = ident.span.normalize_to_macros_2_0();324            (normalized_span, normalized_span)325        } else {326            (ident.span.normalize_to_macro_rules(), ident.span.normalize_to_macros_2_0())327        };328        ident.span = general_span;329        let normalized_ident = Ident { span: normalized_span, ..ident };330331        // Walk backwards up the ribs in scope.332        for (i, rib) in ribs.iter().enumerate().rev() {333            debug!("walk rib\n{:?}", rib.bindings);334            // Use the rib kind to determine whether we are resolving parameters335            // (macro 2.0 hygiene) or local variables (`macro_rules` hygiene).336            let rib_ident = if rib.kind.contains_params() { normalized_ident } else { ident };337            if let Some((original_rib_ident_def, res)) = rib.bindings.get_key_value(&rib_ident) {338                // The ident resolves to a type parameter or local variable.339                return Some(LateDecl::RibDef(self.validate_res_from_ribs(340                    i,341                    rib_ident,342                    *res,343                    finalize.map(|_| general_span),344                    *original_rib_ident_def,345                    ribs,346                    diag_metadata,347                )));348            } else if let RibKind::Block(Some(module)) = rib.kind349                && let Ok(binding) = self.cm_mut().resolve_ident_in_scope_set(350                    ident,351                    ScopeSet::Module(ns, module.to_module()),352                    parent_scope,353                    finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }),354                    ignore_decl,355                    None,356                )357            {358                // The ident resolves to an item in a block.359                return Some(LateDecl::Decl(binding));360            } else if let RibKind::Module(module) = rib.kind {361                // Encountered a module item, abandon ribs and look into that module and preludes.362                let parent_scope = &ParentScope { module: module.to_module(), ..*parent_scope };363                let finalize = finalize.map(|f| Finalize { stage: Stage::Late, ..f });364                return self365                    .cm_mut()366                    .resolve_ident_in_scope_set(367                        orig_ident,368                        ScopeSet::All(ns),369                        parent_scope,370                        finalize,371                        ignore_decl,372                        None,373                    )374                    .ok()375                    .map(LateDecl::Decl);376            }377378            if let RibKind::MacroDefinition(def) = rib.kind379                && def == self.macro_def(ident.span.ctxt())380            {381                // If an invocation of this macro created `ident`, give up on `ident`382                // and switch to `ident`'s source from the macro definition.383                ident.span.remove_mark();384            }385        }386387        unreachable!()388    }389390    /// Resolve an identifier in the specified set of scopes.391    pub(crate) fn resolve_ident_in_scope_set<'r>(392        self: CmResolver<'r, 'ra, 'tcx>,393        orig_ident: Ident,394        scope_set: ScopeSet<'ra>,395        parent_scope: &ParentScope<'ra>,396        finalize: Option<Finalize>,397        ignore_decl: Option<Decl<'ra>>,398        ignore_import: Option<Import<'ra>>,399    ) -> Result<Decl<'ra>, Determinacy> {400        self.resolve_ident_in_scope_set_inner(401            IdentKey::new(orig_ident),402            orig_ident.span,403            scope_set,404            parent_scope,405            finalize,406            ignore_decl,407            ignore_import,408        )409    }410411    fn resolve_ident_in_scope_set_inner<'r>(412        self: CmResolver<'r, 'ra, 'tcx>,413        ident: IdentKey,414        orig_ident_span: Span,415        scope_set: ScopeSet<'ra>,416        parent_scope: &ParentScope<'ra>,417        finalize: Option<Finalize>,418        ignore_decl: Option<Decl<'ra>>,419        ignore_import: Option<Import<'ra>>,420    ) -> Result<Decl<'ra>, Determinacy> {421        // Make sure `self`, `super` etc produce an error when passed to here.422        if ident.name.is_path_segment_keyword() {423            return Err(Determinacy::Determined);424        }425426        let (ns, macro_kind) = match scope_set {427            ScopeSet::All(ns)428            | ScopeSet::Module(ns, _)429            | ScopeSet::ModuleAndExternPrelude(ns, _) => (ns, None),430            ScopeSet::ExternPrelude => (TypeNS, None),431            ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),432        };433        let derive_fallback_lint_id = match finalize {434            Some(Finalize { node_id, stage: Stage::Late, .. }) => Some(node_id),435            _ => None,436        };437438        // This is *the* result, resolution from the scope closest to the resolved identifier.439        // However, sometimes this result is "weak" because it comes from a glob import or440        // a macro expansion, and in this case it cannot shadow names from outer scopes, e.g.441        // mod m { ... } // solution in outer scope442        // {443        //     use prefix::*; // imports another `m` - innermost solution444        //                    // weak, cannot shadow the outer `m`, need to report ambiguity error445        //     m::mac!();446        // }447        // So we have to save the innermost solution and continue searching in outer scopes448        // to detect potential ambiguities.449        let mut innermost_results: SmallVec<[(Decl<'_>, Scope<'_>); 2]> = SmallVec::new();450        let mut determinacy = Determinacy::Determined;451452        // Go through all the scopes and try to resolve the name.453        let break_result = self.visit_scopes(454            scope_set,455            parent_scope,456            ident.ctxt,457            orig_ident_span,458            derive_fallback_lint_id,459            |mut this, scope, use_prelude, ctxt| {460                let ident = IdentKey { name: ident.name, ctxt };461                let res = match this.reborrow().resolve_ident_in_scope(462                    ident,463                    orig_ident_span,464                    ns,465                    scope,466                    use_prelude,467                    scope_set,468                    parent_scope,469                    // Shadowed decls don't need to be marked as used or non-speculatively loaded.470                    if innermost_results.is_empty() { finalize } else { None },471                    ignore_decl,472                    ignore_import,473                ) {474                    Ok(decl) => Ok(decl),475                    // We can break with an error at this step, it means we cannot determine the476                    // resolution right now, but we must block and wait until we can, instead of477                    // considering outer scopes. Although there's no need to do that if we already478                    // have a better solution.479                    Err(ControlFlow::Break(determinacy)) if innermost_results.is_empty() => {480                        return ControlFlow::Break(Err(determinacy));481                    }482                    Err(determinacy) => Err(determinacy.into_value()),483                };484                match res {485                    Ok(decl) if sub_namespace_match(decl.macro_kinds(), macro_kind) => {486                        // Below we report various ambiguity errors.487                        // We do not need to report them if we are either in speculative resolution,488                        // or in late resolution when everything is already imported and expanded489                        // and no ambiguities exist.490                        let import = match finalize {491                            None | Some(Finalize { stage: Stage::Late, .. }) => {492                                return ControlFlow::Break(Ok(decl));493                            }494                            Some(Finalize { import, .. }) => import,495                        };496                        this.get_mut().maybe_push_glob_vs_glob_vis_ambiguity(497                            ident,498                            orig_ident_span,499                            decl,500                            import,501                        );502503                        if let Some(&(innermost_decl, _)) = innermost_results.first() {504                            // Found another solution, if the first one was "weak", report an error.505                            if this.get_mut().maybe_push_ambiguity(506                                ident,507                                orig_ident_span,508                                ns,509                                scope_set,510                                parent_scope,511                                decl,512                                scope,513                                &innermost_results,514                                import,515                            ) {516                                // No need to search for more potential ambiguities, one is enough.517                                return ControlFlow::Break(Ok(innermost_decl));518                            }519                        }520521                        innermost_results.push((decl, scope));522                    }523                    Ok(_) | Err(Determinacy::Determined) => {}524                    Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined,525                }526527                ControlFlow::Continue(())528            },529        );530531        // Scope visiting returned some result early.532        if let Some(break_result) = break_result {533            return break_result;534        }535536        // Scope visiting walked all the scopes and maybe found something in one of them.537        match innermost_results.first() {538            Some(&(decl, ..)) => Ok(decl),539            None => Err(determinacy),540        }541    }542543    fn resolve_ident_in_scope<'r>(544        mut self: CmResolver<'r, 'ra, 'tcx>,545        ident: IdentKey,546        orig_ident_span: Span,547        ns: Namespace,548        scope: Scope<'ra>,549        use_prelude: UsePrelude,550        scope_set: ScopeSet<'ra>,551        parent_scope: &ParentScope<'ra>,552        finalize: Option<Finalize>,553        ignore_decl: Option<Decl<'ra>>,554        ignore_import: Option<Import<'ra>>,555    ) -> Result<Decl<'ra>, ControlFlow<Determinacy, Determinacy>> {556        let ret = match scope {557            Scope::DeriveHelpers(expn_id) => {558                if let Some(decl) = self559                    .helper_attrs560                    .get(&expn_id)561                    .and_then(|attrs| attrs.iter().rfind(|(i, ..)| ident == *i).map(|(.., d)| *d))562                {563                    Ok(decl)564                } else {565                    Err(Determinacy::Determined)566                }567            }568            Scope::DeriveHelpersCompat => {569                let mut result = Err(Determinacy::Determined);570                for derive in parent_scope.derives {571                    let parent_scope = &ParentScope { derives: &[], ..*parent_scope };572                    match self.reborrow().resolve_derive_macro_path(573                        derive,574                        parent_scope,575                        false,576                        ignore_import,577                    ) {578                        Ok((Some(ext), _)) => {579                            if ext.helper_attrs.contains(&ident.name) {580                                let decl = self.arenas.new_pub_def_decl(581                                    Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat),582                                    derive.span,583                                    LocalExpnId::ROOT,584                                );585                                result = Ok(decl);586                                break;587                            }588                        }589                        Ok(_) | Err(Determinacy::Determined) => {}590                        Err(Determinacy::Undetermined) => result = Err(Determinacy::Undetermined),591                    }592                }593                result594            }595            Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() {596                MacroRulesScope::Def(macro_rules_def) if ident == macro_rules_def.ident => {597                    Ok(macro_rules_def.decl)598                }599                MacroRulesScope::Invocation(_) => Err(Determinacy::Undetermined),600                _ => Err(Determinacy::Determined),601            },602            Scope::ModuleNonGlobs(module, derive_fallback_lint_id) => {603                let (adjusted_parent_scope, adjusted_finalize) = if matches!(604                    scope_set,605                    ScopeSet::Module(..) | ScopeSet::ModuleAndExternPrelude(..)606                ) {607                    (parent_scope, finalize)608                } else {609                    (610                        &ParentScope { module, ..*parent_scope },611                        finalize.map(|f| Finalize { used: Used::Scope, ..f }),612                    )613                };614                let shadowing = if matches!(scope_set, ScopeSet::Module(..)) {615                    Shadowing::Unrestricted616                } else {617                    Shadowing::Restricted618                };619                let decl = if module.is_local() {620                    self.reborrow().resolve_ident_in_local_module_non_globs_unadjusted(621                        module.expect_local(),622                        ident,623                        orig_ident_span,624                        ns,625                        adjusted_parent_scope,626                        shadowing,627                        adjusted_finalize,628                        ignore_decl,629                        ignore_import,630                    )631                } else {632                    self.reborrow().resolve_ident_in_extern_module_non_globs_unadjusted(633                        module.expect_extern(),634                        ident,635                        orig_ident_span,636                        ns,637                        adjusted_parent_scope,638                        shadowing,639                        adjusted_finalize,640                        ignore_decl,641                    )642                };643644                match decl {645                    Ok(decl) => {646                        if let Some(lint_id) = derive_fallback_lint_id {647                            self.get_mut().lint_buffer.buffer_lint(648                                PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,649                                lint_id,650                                orig_ident_span,651                                diagnostics::ProcMacroDeriveResolutionFallback {652                                    span: orig_ident_span,653                                    ns_descr: ns.descr(),654                                    ident: ident.name,655                                },656                            );657                        }658                        Ok(decl)659                    }660                    Err(ControlFlow::Continue(determinacy)) => Err(determinacy),661                    Err(ControlFlow::Break(..)) => return decl,662                }663            }664            Scope::ModuleGlobs(module, _) if !module.is_local() => {665                // Fast path: external module decoding only creates non-glob declarations.666                Err(Determined)667            }668            Scope::ModuleGlobs(module, derive_fallback_lint_id) => {669                let (adjusted_parent_scope, adjusted_finalize) = if matches!(670                    scope_set,671                    ScopeSet::Module(..) | ScopeSet::ModuleAndExternPrelude(..)672                ) {673                    (parent_scope, finalize)674                } else {675                    (676                        &ParentScope { module, ..*parent_scope },677                        finalize.map(|f| Finalize { used: Used::Scope, ..f }),678                    )679                };680                let binding = self.reborrow().resolve_ident_in_module_globs_unadjusted(681                    module.expect_local(),682                    ident,683                    orig_ident_span,684                    ns,685                    adjusted_parent_scope,686                    if matches!(scope_set, ScopeSet::Module(..)) {687                        Shadowing::Unrestricted688                    } else {689                        Shadowing::Restricted690                    },691                    adjusted_finalize,692                    ignore_decl,693                    ignore_import,694                );695                match binding {696                    Ok(binding) => {697                        if let Some(lint_id) = derive_fallback_lint_id {698                            self.get_mut().lint_buffer.buffer_lint(699                                PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,700                                lint_id,701                                orig_ident_span,702                                diagnostics::ProcMacroDeriveResolutionFallback {703                                    span: orig_ident_span,704                                    ns_descr: ns.descr(),705                                    ident: ident.name,706                                },707                            );708                        }709                        Ok(binding)710                    }711                    Err(ControlFlow::Continue(determinacy)) => Err(determinacy),712                    Err(ControlFlow::Break(..)) => return binding,713                }714            }715            Scope::MacroUsePrelude => match self.macro_use_prelude.get(&ident.name).cloned() {716                Some(decl) => Ok(decl),717                None => {718                    Err(Determinacy::determined(!self.graph_root.has_unexpanded_invocations(&self)))719                }720            },721            Scope::BuiltinAttrs => match self.builtin_attr_decls.get(&ident.name) {722                Some(decl) => Ok(*decl),723                None => Err(Determinacy::Determined),724            },725            Scope::ExternPreludeItems => {726                match self.reborrow().extern_prelude_get_item(727                    ident,728                    orig_ident_span,729                    finalize.is_some(),730                ) {731                    Some(decl) => Ok(decl),732                    None => Err(Determinacy::determined(733                        !self.graph_root.has_unexpanded_invocations(&self),734                    )),735                }736            }737            Scope::ExternPreludeFlags => {738                match self.extern_prelude_get_flag(ident, orig_ident_span, finalize.is_some()) {739                    Some(decl) => Ok(decl),740                    None => Err(Determinacy::Determined),741                }742            }743            Scope::ToolAttributePrelude => match self.registered_attr_tool_decls.get(&ident) {744                Some(decl) => Ok(*decl),745                None => Err(Determinacy::Determined),746            },747            Scope::StdLibPrelude => {748                let mut result = Err(Determinacy::Determined);749                if let Some(prelude) = self.prelude750                    && let Ok(decl) = self.reborrow().resolve_ident_in_scope_set_inner(751                        ident,752                        orig_ident_span,753                        ScopeSet::Module(ns, prelude),754                        parent_scope,755                        None,756                        ignore_decl,757                        ignore_import,758                    )759                    && (matches!(use_prelude, UsePrelude::Yes) || self.is_builtin_macro(decl.res()))760                {761                    result = Ok(decl)762                }763764                result765            }766            Scope::BuiltinTypes => match self.builtin_type_decls.get(&ident.name) {767                Some(decl) => {768                    if matches!(ident.name, sym::f16)769                        && !self.features.f16()770                        && !orig_ident_span.allows_unstable(sym::f16)771                        && finalize.is_some()772                    {773                        feature_err(774                            self.tcx.sess,775                            sym::f16,776                            orig_ident_span,777                            "the type `f16` is unstable",778                        )779                        .emit();780                    }781                    if matches!(ident.name, sym::f128)782                        && !self.features.f128()783                        && !orig_ident_span.allows_unstable(sym::f128)784                        && finalize.is_some()785                    {786                        feature_err(787                            self.tcx.sess,788                            sym::f128,789                            orig_ident_span,790                            "the type `f128` is unstable",791                        )792                        .emit();793                    }794                    Ok(*decl)795                }796                None => Err(Determinacy::Determined),797            },798        };799800        ret.map_err(ControlFlow::Continue)801    }802803    fn maybe_push_glob_vs_glob_vis_ambiguity(804        &mut self,805        ident: IdentKey,806        orig_ident_span: Span,807        decl: Decl<'ra>,808        import: Option<ImportSummary>,809    ) {810        let Some(import) = import else { return };811        let vis1 = self.import_decl_vis(decl, import);812        let vis2 = self.import_decl_vis_ext(decl, import, true);813        if vis1 != vis2 {814            self.ambiguity_errors.push(AmbiguityError {815                kind: AmbiguityKind::GlobVsGlob,816                ambig_vis: Some((vis1, vis2)),817                ident: ident.orig(orig_ident_span),818                b1: decl.ambiguity_vis_max.get().unwrap_or(decl),819                b2: decl.ambiguity_vis_min.get().unwrap_or(decl),820                scope1: Scope::ModuleGlobs(decl.parent_module.unwrap(), None),821                scope2: Scope::ModuleGlobs(decl.parent_module.unwrap(), None),822                warning: Some(AmbiguityWarning::GlobImport),823            });824        }825    }826827    fn maybe_push_ambiguity(828        &mut self,829        ident: IdentKey,830        orig_ident_span: Span,831        ns: Namespace,832        scope_set: ScopeSet<'ra>,833        parent_scope: &ParentScope<'ra>,834        decl: Decl<'ra>,835        scope: Scope<'ra>,836        innermost_results: &[(Decl<'ra>, Scope<'ra>)],837        import: Option<ImportSummary>,838    ) -> bool {839        let (innermost_decl, innermost_scope) = innermost_results[0];840        let (res, innermost_res) = (decl.res(), innermost_decl.res());841        let ambig_vis = if res != innermost_res {842            None843        } else if let Some(import) = import844            && let vis1 = self.import_decl_vis(decl, import)845            && let vis2 = self.import_decl_vis(innermost_decl, import)846            && vis1 != vis2847        {848            Some((vis1, vis2))849        } else {850            return false;851        };852853        // FIXME: Use `scope` instead of `res` to detect built-in attrs and derive helpers,854        // it will exclude imports, make slightly more code legal, and will require lang approval.855        let module_only = matches!(scope_set, ScopeSet::Module(..));856        let is_builtin = |res| matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Builtin(..)));857        let derive_helper = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);858        let derive_helper_compat = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat);859860        let ambiguity_error_kind = if is_builtin(innermost_res) || is_builtin(res) {861            Some(AmbiguityKind::BuiltinAttr)862        } else if innermost_res == derive_helper_compat {863            Some(AmbiguityKind::DeriveHelper)864        } else if res == derive_helper_compat && innermost_res != derive_helper {865            span_bug!(orig_ident_span, "impossible inner resolution kind")866        } else if matches!(innermost_scope, Scope::MacroRules(_))867            && matches!(scope, Scope::ModuleNonGlobs(..) | Scope::ModuleGlobs(..))868            && !self.disambiguate_macro_rules_vs_modularized(innermost_decl, decl)869        {870            Some(AmbiguityKind::MacroRulesVsModularized)871        } else if matches!(scope, Scope::MacroRules(_))872            && matches!(innermost_scope, Scope::ModuleNonGlobs(..) | Scope::ModuleGlobs(..))873        {874            // should be impossible because of visitation order in875            // visit_scopes876            //877            // we visit all macro_rules scopes (e.g. textual scope macros)878            // before we visit any modules (e.g. path-based scope macros)879            span_bug!(880                orig_ident_span,881                "ambiguous scoped macro resolutions with path-based \882                                        scope resolution as first candidate"883            )884        } else if innermost_decl.is_glob_import() {885            Some(AmbiguityKind::GlobVsOuter)886        } else if !module_only && innermost_decl.may_appear_after(parent_scope.expansion, decl) {887            Some(AmbiguityKind::MoreExpandedVsOuter)888        } else if innermost_decl.expansion != LocalExpnId::ROOT889            && (!module_only || ns == MacroNS)890            && let Scope::ModuleGlobs(m1, _) = scope891            && let Scope::ModuleNonGlobs(m2, _) = innermost_scope892            && m1 == m2893        {894            // FIXME: this error is too conservative and technically unnecessary now when module895            // scope is split into two scopes, at least when not resolving in `ScopeSet::Module`,896            // remove it with lang team approval.897            Some(AmbiguityKind::GlobVsExpanded)898        } else {899            None900        };901902        if let Some(kind) = ambiguity_error_kind {903            // Skip ambiguity errors for extern flag bindings "overridden"904            // by extern item bindings.905            // FIXME: Remove with lang team approval.906            let issue_145575_hack = matches!(scope, Scope::ExternPreludeFlags)907                && innermost_results[1..]908                    .iter()909                    .any(|(b, s)| matches!(s, Scope::ExternPreludeItems) && *b != innermost_decl);910            // Skip ambiguity errors for nonglob module bindings "overridden"911            // by glob module bindings in the same module.912            // FIXME: Remove with lang team approval.913            let issue_149681_hack = match scope {914                Scope::ModuleGlobs(m1, _)915                    if innermost_results[1..]916                        .iter()917                        .any(|(_, s)| matches!(*s, Scope::ModuleNonGlobs(m2, _) if m1 == m2)) =>918                {919                    true920                }921                _ => false,922            };923924            if issue_145575_hack || issue_149681_hack {925                self.issue_145575_hack_applied = true;926            } else {927                // Turn ambiguity errors for core vs std panic into warnings.928                // FIXME: Remove with lang team approval.929                let is_issue_147319_hack = orig_ident_span.edition() <= Edition::Edition2024930                    && matches!(ident.name, sym::panic)931                    && matches!(scope, Scope::StdLibPrelude)932                    && matches!(innermost_scope, Scope::ModuleGlobs(_, _))933                    && ((self.is_specific_builtin_macro(res, sym::std_panic)934                        && self.is_specific_builtin_macro(innermost_res, sym::core_panic))935                        || (self.is_specific_builtin_macro(res, sym::core_panic)936                            && self.is_specific_builtin_macro(innermost_res, sym::std_panic)));937938                let warning = if ambig_vis.is_some() {939                    Some(AmbiguityWarning::GlobImport)940                } else if is_issue_147319_hack {941                    Some(AmbiguityWarning::PanicImport)942                } else {943                    None944                };945946                self.ambiguity_errors.push(AmbiguityError {947                    kind,948                    ambig_vis,949                    ident: ident.orig(orig_ident_span),950                    b1: innermost_decl,951                    b2: decl,952                    scope1: innermost_scope,953                    scope2: scope,954                    warning,955                });956                return true;957            }958        }959960        false961    }962963    #[instrument(level = "debug", skip(self))]964    pub(crate) fn maybe_resolve_ident_in_module<'r>(965        self: CmResolver<'r, 'ra, 'tcx>,966        module: ModuleOrUniformRoot<'ra>,967        ident: Ident,968        ns: Namespace,969        parent_scope: &ParentScope<'ra>,970        ignore_import: Option<Import<'ra>>,971    ) -> Result<Decl<'ra>, Determinacy> {972        self.resolve_ident_in_module(module, ident, ns, parent_scope, None, None, ignore_import)973    }974975    fn resolve_super_in_module(976        &self,977        ident: Ident,978        module: Option<Module<'ra>>,979        parent_scope: &ParentScope<'ra>,980    ) -> Option<Module<'ra>> {981        let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();982        module983            .unwrap_or_else(|| self.resolve_self(&mut ctxt, parent_scope.module))984            .parent985            .map(|parent| self.resolve_self(&mut ctxt, parent))986    }987988    pub(crate) fn path_root_is_crate_root(&self, ident: Ident) -> bool {989        ident.name == kw::PathRoot && ident.span.is_rust_2015() && self.tcx.sess.is_rust_2015()990    }991992    #[instrument(level = "debug", skip(self))]993    pub(crate) fn resolve_ident_in_module<'r>(994        self: CmResolver<'r, 'ra, 'tcx>,995        module: ModuleOrUniformRoot<'ra>,996        ident: Ident,997        ns: Namespace,998        parent_scope: &ParentScope<'ra>,999        finalize: Option<Finalize>,1000        ignore_decl: Option<Decl<'ra>>,1001        ignore_import: Option<Import<'ra>>,1002    ) -> Result<Decl<'ra>, Determinacy> {1003        match module {1004            ModuleOrUniformRoot::Module(module) => {1005                if ns == TypeNS {1006                    if ident.name == kw::SelfLower {1007                        return Ok(module.self_decl.unwrap());1008                    }1009                    if ident.name == kw::Super1010                        && let Some(module) =1011                            self.resolve_super_in_module(ident, Some(module), parent_scope)1012                    {1013                        return Ok(module.self_decl.unwrap());1014                    }1015                }10161017                let (ident_key, def) = IdentKey::new_adjusted(ident, module.expansion);1018                let adjusted_parent_scope = match def {1019                    Some(def) => ParentScope { module: self.expn_def_scope(def), ..*parent_scope },1020                    None => *parent_scope,1021                };1022                self.resolve_ident_in_scope_set_inner(1023                    ident_key,1024                    ident.span,1025                    ScopeSet::Module(ns, module),1026                    &adjusted_parent_scope,1027                    finalize,1028                    ignore_decl,1029                    ignore_import,1030                )1031            }1032            ModuleOrUniformRoot::OpenModule(sym) => {1033                let open_ns_name = format!("{}::{}", sym.as_str(), ident.name);1034                let ns_ident = IdentKey::with_root_ctxt(Symbol::intern(&open_ns_name));1035                match self.extern_prelude_get_flag(ns_ident, ident.span, finalize.is_some()) {1036                    Some(decl) => Ok(decl),1037                    None => Err(Determinacy::Determined),1038                }1039            }1040            ModuleOrUniformRoot::ModuleAndExternPrelude(module) => self.resolve_ident_in_scope_set(1041                ident,1042                ScopeSet::ModuleAndExternPrelude(ns, module),1043                parent_scope,1044                finalize,1045                ignore_decl,1046                ignore_import,1047            ),1048            ModuleOrUniformRoot::ExternPrelude => {1049                if ns != TypeNS {1050                    Err(Determined)1051                } else {1052                    self.resolve_ident_in_scope_set_inner(1053                        IdentKey::new_adjusted(ident, ExpnId::root()).0,1054                        ident.span,1055                        ScopeSet::ExternPrelude,1056                        parent_scope,1057                        finalize,1058                        ignore_decl,1059                        ignore_import,1060                    )1061                }1062            }1063            ModuleOrUniformRoot::CurrentScope => {1064                if ns == TypeNS {1065                    if ident.name == kw::SelfLower {1066                        let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();1067                        let module = self.resolve_self(&mut ctxt, parent_scope.module);1068                        return Ok(module.self_decl.unwrap());1069                    }1070                    if ident.name == kw::Super1071                        && let Some(module) =1072                            self.resolve_super_in_module(ident, None, parent_scope)1073                    {1074                        return Ok(module.self_decl.unwrap());1075                    }1076                    if ident.name == kw::Crate1077                        || ident.name == kw::DollarCrate1078                        || self.path_root_is_crate_root(ident)1079                    {1080                        let module = self.resolve_crate_root(ident);1081                        return Ok(module.self_decl.unwrap());1082                    }1083                }10841085                self.resolve_ident_in_scope_set(1086                    ident,1087                    ScopeSet::All(ns),1088                    parent_scope,1089                    finalize,1090                    ignore_decl,1091                    ignore_import,1092                )1093            }1094        }1095    }10961097    /// Attempts to resolve `ident` in namespace `ns` of non-glob bindings in an external `module`.1098    fn resolve_ident_in_extern_module_non_globs_unadjusted<'r>(1099        mut self: CmResolver<'r, 'ra, 'tcx>,1100        module: ExternModule<'ra>,1101        ident: IdentKey,1102        orig_ident_span: Span,1103        ns: Namespace,1104        parent_scope: &ParentScope<'ra>,1105        shadowing: Shadowing,1106        finalize: Option<Finalize>,1107        // This binding should be ignored during in-module resolution, so that we don't get1108        // "self-confirming" import resolutions during import validation and checking.1109        ignore_decl: Option<Decl<'ra>>,1110    ) -> Result<Decl<'ra>, ControlFlow<Determinacy, Determinacy>> {1111        let key = BindingKey::new(ident, ns);1112        let resolution =1113            &*self.resolution(module.to_module(), key).ok_or(ControlFlow::Continue(Determined))?;11141115        let binding = resolution.non_glob_decl.filter(|b| Some(*b) != ignore_decl);11161117        if let Some(finalize) = finalize {1118            return self.get_mut().finalize_module_binding(1119                ident,1120                orig_ident_span,1121                binding,1122                parent_scope,1123                finalize,1124                shadowing,1125            );1126        }11271128        // Items and single imports are not shadowable, if we have one, then it's determined.1129        if let Some(binding) = binding {1130            let accessible = self.is_accessible_from(binding.vis(), parent_scope.module);1131            return if accessible { Ok(binding) } else { Err(ControlFlow::Break(Determined)) };1132        }1133        Err(ControlFlow::Continue(Determined))1134    }11351136    /// Attempts to resolve `ident` in namespace `ns` of non-glob bindings in a local `module`.1137    fn resolve_ident_in_local_module_non_globs_unadjusted<'r>(1138        mut self: CmResolver<'r, 'ra, 'tcx>,1139        module: LocalModule<'ra>,1140        ident: IdentKey,1141        orig_ident_span: Span,1142        ns: Namespace,1143        parent_scope: &ParentScope<'ra>,1144        shadowing: Shadowing,1145        finalize: Option<Finalize>,1146        // This binding should be ignored during in-module resolution, so that we don't get1147        // "self-confirming" import resolutions during import validation and checking.1148        ignore_decl: Option<Decl<'ra>>,1149        ignore_import: Option<Import<'ra>>,1150    ) -> Result<Decl<'ra>, ControlFlow<Determinacy, Determinacy>> {1151        let key = BindingKey::new(ident, ns);1152        let resolution = self.resolution(module.to_module(), key);11531154        let binding =1155            resolution.as_ref().and_then(|r| r.non_glob_decl).filter(|b| Some(*b) != ignore_decl);11561157        if let Some(finalize) = finalize {1158            // finalize implies that the module is fully expanded1159            assert!(!module.has_unexpanded_invocations(&self));1160            return self.get_mut().finalize_module_binding(1161                ident,1162                orig_ident_span,1163                binding,1164                parent_scope,1165                finalize,1166                shadowing,1167            );1168        }11691170        // Items and single imports are not shadowable, if we have one, then it's determined.1171        if let Some(binding) = binding {1172            let accessible = self.is_accessible_from(binding.vis(), parent_scope.module);1173            return if accessible { Ok(binding) } else { Err(ControlFlow::Break(Determined)) };1174        }11751176        if let Some(resolution) = resolution {1177            // We need to detect resolution cycles to avoid infinite recursion. The guard ensures1178            // the resolution is removed when this resolve call ends.1179            let _cycle_guard = cycle_detection::enter_cycle_detector(module, key)1180                .map_err(|_| ControlFlow::Continue(Determined))?;11811182            // Check if one of single imports can still define the name, block if it can.1183            if self.reborrow().single_import_can_define_name(1184                &resolution,1185                None,1186                ns,1187                ignore_import,1188                ignore_decl,1189                parent_scope,1190            ) {1191                return Err(ControlFlow::Break(Undetermined));1192            }1193        }11941195        // Check if one of unexpanded macros can still define the name.1196        if module.has_unexpanded_invocations(&self) {1197            return Err(ControlFlow::Continue(Undetermined));1198        }11991200        // No resolution and no one else can define the name - determinate error.1201        Err(ControlFlow::Continue(Determined))1202    }12031204    /// Attempts to resolve `ident` in namespace `ns` of glob bindings in `module`.1205    fn resolve_ident_in_module_globs_unadjusted<'r>(1206        mut self: CmResolver<'r, 'ra, 'tcx>,1207        module: LocalModule<'ra>,1208        ident: IdentKey,1209        orig_ident_span: Span,1210        ns: Namespace,1211        parent_scope: &ParentScope<'ra>,1212        shadowing: Shadowing,1213        finalize: Option<Finalize>,1214        ignore_decl: Option<Decl<'ra>>,1215        ignore_import: Option<Import<'ra>>,1216    ) -> Result<Decl<'ra>, ControlFlow<Determinacy, Determinacy>> {1217        let key = BindingKey::new(ident, ns);1218        let resolution = self.resolution(module.to_module(), key);12191220        let binding =1221            resolution.as_ref().and_then(|r| r.glob_decl).filter(|b| Some(*b) != ignore_decl);12221223        if let Some(finalize) = finalize {1224            // finalize implies that the module is fully expanded1225            assert!(!module.has_unexpanded_invocations(&self));1226            return self.get_mut().finalize_module_binding(1227                ident,1228                orig_ident_span,1229                binding,1230                parent_scope,1231                finalize,1232                shadowing,1233            );1234        }12351236        // We need to detect resolution cycles to avoid infinite recursion. The guard ensures1237        // the resolution is removed when this resolve call ends.1238        let _cycle_guard = cycle_detection::enter_cycle_detector(module, key)1239            .map_err(|_| ControlFlow::Continue(Determined))?;12401241        // Check if one of single imports can still define the name,1242        // if it can then our result is not determined and can be invalidated.1243        if let Some(resolution) = resolution {1244            if self.reborrow().single_import_can_define_name(1245                &resolution,1246                binding,1247                ns,1248                ignore_import,1249                ignore_decl,1250                parent_scope,1251            ) {1252                return Err(ControlFlow::Break(Undetermined));1253            }1254        }12551256        // So we have a resolution that's from a glob import. This resolution is determined1257        // if it cannot be shadowed by some new item/import expanded from a macro.1258        // This happens either if there are no unexpanded macros, or expanded names cannot1259        // shadow globs (that happens in macro namespace or with restricted shadowing).1260        //1261        // Additionally, any macro in any module can plant names in the root module if it creates1262        // `macro_export` macros, so the root module effectively has unresolved invocations if any1263        // module has unresolved invocations.1264        // However, it causes resolution/expansion to stuck too often (#53144), so, to make1265        // progress, we have to ignore those potential unresolved invocations from other modules1266        // and prohibit access to macro-expanded `macro_export` macros instead (unless restricted1267        // shadowing is enabled, see `macro_expanded_macro_export_errors`).1268        if let Some(binding) = binding {1269            return if binding.determined(&self)1270                || ns == MacroNS1271                || shadowing == Shadowing::Restricted1272            {1273                let accessible = self.is_accessible_from(binding.vis(), parent_scope.module);1274                if accessible { Ok(binding) } else { Err(ControlFlow::Break(Determined)) }1275            } else {1276                Err(ControlFlow::Break(Undetermined))1277            };1278        }12791280        // Now we are in situation when new item/import can appear only from a glob or a macro1281        // expansion. With restricted shadowing names from globs and macro expansions cannot1282        // shadow names from outer scopes, so we can freely fallback from module search to search1283        // in outer scopes. For `resolve_ident_in_scope_set` to continue search in outer1284        // scopes we return `Undetermined` with `ControlFlow::Continue`.1285        // Check if one of unexpanded macros can still define the name,1286        // if it can then our "no resolution" result is not determined and can be invalidated.1287        if module.has_unexpanded_invocations(&self) {1288            return Err(ControlFlow::Continue(Undetermined));1289        }12901291        // Check if one of glob imports can still define the name,1292        // if it can then our "no resolution" result is not determined and can be invalidated.1293        for glob_import in module.globs.borrow_checked(&self).iter() {1294            if ignore_import == Some(*glob_import) {1295                continue;1296            }1297            if !self.is_accessible_from(glob_import.vis, parent_scope.module) {1298                continue;1299            }1300            let module = match glob_import.imported_module.get() {1301                Some(ModuleOrUniformRoot::Module(module)) => module,1302                Some(_) => continue,1303                None => return Err(ControlFlow::Continue(Undetermined)),1304            };1305            let tmp_parent_scope;1306            let (mut adjusted_parent_scope, mut adjusted_ident) = (parent_scope, ident);1307            match adjusted_ident1308                .ctxt1309                .update_unchecked(|ctxt| ctxt.glob_adjust(module.expansion, glob_import.span))1310            {1311                Some(Some(def)) => {1312                    tmp_parent_scope =1313                        ParentScope { module: self.expn_def_scope(def), ..*parent_scope };1314                    adjusted_parent_scope = &tmp_parent_scope;1315                }1316                Some(None) => {}1317                None => continue,1318            };1319            let result = self.reborrow().resolve_ident_in_scope_set_inner(1320                adjusted_ident,1321                orig_ident_span,1322                ScopeSet::Module(ns, module),1323                adjusted_parent_scope,1324                None,1325                ignore_decl,1326                ignore_import,1327            );13281329            match result {1330                Err(Determined) => continue,1331                Ok(binding)1332                    if !self.is_accessible_from(binding.vis(), glob_import.parent_scope.module) =>1333                {1334                    continue;1335                }1336                Ok(_) | Err(Undetermined) => return Err(ControlFlow::Continue(Undetermined)),1337            }1338        }13391340        // No resolution and no one else can define the name - determinate error.1341        Err(ControlFlow::Continue(Determined))1342    }13431344    fn finalize_module_binding(1345        &mut self,1346        ident: IdentKey,1347        orig_ident_span: Span,1348        binding: Option<Decl<'ra>>,1349        parent_scope: &ParentScope<'ra>,1350        finalize: Finalize,1351        shadowing: Shadowing,1352    ) -> Result<Decl<'ra>, ControlFlow<Determinacy, Determinacy>> {1353        let Finalize { path_span, report_private, used, root_span, .. } = finalize;13541355        let Some(binding) = binding else {1356            return Err(ControlFlow::Continue(Determined));1357        };13581359        let ident = ident.orig(orig_ident_span);1360        if !self.is_accessible_from(binding.vis(), parent_scope.module) {1361            if report_private {1362                self.privacy_errors.push(PrivacyError {1363                    ident,1364                    decl: binding,1365                    dedup_span: path_span,1366                    outermost_res: None,1367                    source: None,1368                    parent_scope: *parent_scope,1369                    single_nested: path_span != root_span,1370                });1371            } else {1372                return Err(ControlFlow::Break(Determined));1373            }1374        }13751376        if shadowing == Shadowing::Unrestricted1377            && binding.expansion != LocalExpnId::ROOT1378            && let DeclKind::Import { import, .. } = binding.kind1379            && matches!(import.kind, ImportKind::MacroExport)1380        {1381            self.macro_expanded_macro_export_errors.insert((path_span, binding.span));1382        }13831384        self.record_use(ident, binding, used);1385        return Ok(binding);1386    }13871388    // Checks if a single import can define the `Ident` corresponding to `binding`.1389    // This is used to check whether we can definitively accept a glob as a resolution.1390    fn single_import_can_define_name<'r>(1391        mut self: CmResolver<'r, 'ra, 'tcx>,1392        resolution: &NameResolution<'ra>,1393        binding: Option<Decl<'ra>>,1394        ns: Namespace,1395        ignore_import: Option<Import<'ra>>,1396        ignore_decl: Option<Decl<'ra>>,1397        parent_scope: &ParentScope<'ra>,1398    ) -> bool {1399        for single_import in &resolution.single_imports {1400            if let Some(decl) = resolution.non_glob_decl1401                && let DeclKind::Import { import, .. } = decl.kind1402                && import == *single_import1403            {1404                // Single import has already defined the name and we are aware of it,1405                // no need to block the globs.1406                continue;1407            }1408            if ignore_import == Some(*single_import) {1409                continue;1410            }1411            if !self.is_accessible_from(single_import.vis, parent_scope.module) {1412                continue;1413            }1414            if let Some(ignored) = ignore_decl1415                && let DeclKind::Import { import, .. } = ignored.kind1416                && import == *single_import1417            {1418                continue;1419            }14201421            let Some(module) = single_import.imported_module.get() else {1422                return true;1423            };1424            let ImportKind::Single { source, target, decls, .. } = &single_import.kind else {1425                unreachable!();1426            };1427            if source != target {1428                if decls.iter().all(|d| d.get().decl().is_none()) {1429                    return true;1430                } else if decls[ns].get().decl().is_none() && binding.is_some() {1431                    return true;1432                }1433            }14341435            match self.reborrow().resolve_ident_in_module(1436                module,1437                *source,1438                ns,1439                &single_import.parent_scope,1440                None,1441                ignore_decl,1442                None,1443            ) {1444                Err(Determined) => continue,1445                Ok(binding)1446                    if !self1447                        .is_accessible_from(binding.vis(), single_import.parent_scope.module) =>1448                {1449                    continue;1450                }1451                Ok(_) | Err(Undetermined) => return true,1452            }1453        }14541455        false1456    }14571458    /// Validate a local resolution (from ribs).1459    #[instrument(level = "debug", skip(self, all_ribs))]1460    fn validate_res_from_ribs(1461        &self,1462        rib_index: usize,1463        rib_ident: Ident,1464        res: Res,1465        finalize: Option<Span>,1466        original_rib_ident_def: Ident,1467        all_ribs: &[Rib<'ra>],1468        diag_metadata: Option<&DiagMetadata<'_>>,1469    ) -> Res {1470        debug!("validate_res_from_ribs({:?})", res);1471        let ribs = &all_ribs[rib_index + 1..];14721473        // An invalid forward use of a generic parameter from a previous default1474        // or in a const param ty.1475        if let RibKind::ForwardGenericParamBan(reason) = all_ribs[rib_index].kind {1476            if let Some(span) = finalize {1477                let res_error = if rib_ident.name == kw::SelfUpper {1478                    ResolutionError::ForwardDeclaredSelf(reason)1479                } else {1480                    ResolutionError::ForwardDeclaredGenericParam(rib_ident.name, reason)1481                };1482                self.report_error(span, res_error);1483            }1484            assert_eq!(res, Res::Err);1485            return Res::Err;1486        }14871488        match res {1489            Res::Local(_) => {1490                use ResolutionError::*;1491                let mut res_err = None;14921493                for rib in ribs {1494                    match rib.kind {1495                        RibKind::Normal1496                        | RibKind::Block(..)1497                        | RibKind::FnOrCoroutine1498                        | RibKind::Module(..)1499                        | RibKind::MacroDefinition(..)1500                        | RibKind::ForwardGenericParamBan(_) => {1501                            // Nothing to do. Continue.1502                        }1503                        RibKind::Item(..) | RibKind::AssocItem => {1504                            // This was an attempt to access an upvar inside a1505                            // named function item. This is not allowed, so we1506                            // report an error.1507                            if let Some(span) = finalize {1508                                // We don't immediately trigger a resolve error, because1509                                // we want certain other resolution errors (namely those1510                                // emitted for `ConstantItemRibKind` below) to take1511                                // precedence.1512                                res_err = Some((span, CannotCaptureDynamicEnvironmentInFnItem));1513                            }1514                        }1515                        RibKind::ConstantItem(_, item) => {1516                            // Still doesn't deal with upvars1517                            if let Some(span) = finalize {1518                                let (span, resolution_error) = match item {1519                                    None if rib_ident.name == kw::SelfLower => {1520                                        (span, LowercaseSelf)1521                                    }1522                                    None => {1523                                        // If we have a `let name = expr;`, we have the span for1524                                        // `name` and use that to see if it is followed by a type1525                                        // specifier. If not, then we know we need to suggest1526                                        // `const name: Ty = expr;`. This is a heuristic, it will1527                                        // break down in the presence of macros.1528                                        let sm = self.tcx.sess.source_map();1529                                        let type_span = match sm1530                                            .span_followed_by(original_rib_ident_def.span, ":")1531                                        {1532                                            None => {1533                                                Some(original_rib_ident_def.span.shrink_to_hi())1534                                            }1535                                            Some(_) => None,1536                                        };1537                                        (1538                                            rib_ident.span,1539                                            AttemptToUseNonConstantValueInConstant {1540                                                ident: original_rib_ident_def,1541                                                suggestion: "const",1542                                                current: "let",1543                                                type_span,1544                                            },1545                                        )1546                                    }1547                                    Some((ident, kind)) => (1548                                        span,1549                                        AttemptToUseNonConstantValueInConstant {1550                                            ident,1551                                            suggestion: "let",1552                                            current: kind.as_str(),1553                                            type_span: None,1554                                        },1555                                    ),1556                                };1557                                self.report_error(span, resolution_error);1558                            }1559                            return Res::Err;1560                        }1561                        RibKind::ConstParamTy => {1562                            if let Some(span) = finalize {1563                                self.report_error(1564                                    span,1565                                    ParamInTyOfConstParam { name: rib_ident.name },1566                                );1567                            }1568                            return Res::Err;1569                        }1570                        RibKind::InlineAsmSym => {1571                            if let Some(span) = finalize {1572                                self.report_error(span, InvalidAsmSym);1573                            }1574                            return Res::Err;1575                        }1576                    }1577                }1578                if let Some((span, res_err)) = res_err {1579                    self.report_error(span, res_err);1580                    return Res::Err;1581                }1582            }1583            Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {1584                for rib in ribs {1585                    let (has_generic_params, def_kind) = match rib.kind {1586                        RibKind::Normal1587                        | RibKind::Block(..)1588                        | RibKind::FnOrCoroutine1589                        | RibKind::Module(..)1590                        | RibKind::MacroDefinition(..)1591                        | RibKind::InlineAsmSym1592                        | RibKind::AssocItem1593                        | RibKind::ForwardGenericParamBan(_) => {1594                            // Nothing to do. Continue.1595                            continue;1596                        }15971598                        RibKind::ConstParamTy => {1599                            let adt_enabled = self.features.min_adt_const_params()1600                                || self.features.adt_const_params();1601                            let is_self = matches!(res, Res::SelfTyAlias { .. });1602                            // We check whether Self depends on generics parameters in `fn type_of`1603                            if self.features.generic_const_parameter_types()1604                                || (adt_enabled && is_self)1605                            {1606                                continue;1607                            } else {1608                                if let Some(span) = finalize {1609                                    if matches!(res, Res::SelfTyAlias { .. }) {1610                                        self.report_error(span, ResolutionError::SelfInConstParam);1611                                    } else {1612                                        self.report_error(1613                                            span,1614                                            ResolutionError::ParamInTyOfConstParam {1615                                                name: rib_ident.name,1616                                            },1617                                        );1618                                    }1619                                }1620                                return Res::Err;1621                            }1622                        }16231624                        RibKind::ConstantItem(trivial, _) => {1625                            if let ConstantHasGenerics::No(cause) = trivial1626                                && !matches!(res, Res::SelfTyAlias { .. })1627                            {1628                                if let Some(span) = finalize {1629                                    let error = match cause {1630                                        NoConstantGenericsReason::IsEnumDiscriminant => {1631                                            ResolutionError::ParamInEnumDiscriminant {1632                                                name: rib_ident.name,1633                                                param_kind: ParamKindInEnumDiscriminant::Type,1634                                            }1635                                        }1636                                        NoConstantGenericsReason::NonTrivialConstArg => {1637                                            ResolutionError::ParamInNonTrivialAnonConst {1638                                                is_gca: self.features.generic_const_args(),1639                                                name: rib_ident.name,1640                                                param_kind: ParamKindInNonTrivialAnonConst::Type,1641                                            }1642                                        }1643                                    };1644                                    let _: ErrorGuaranteed = self.report_error(span, error);1645                                }16461647                                return Res::Err;1648                            }16491650                            continue;1651                        }16521653                        // This was an attempt to use a type parameter outside its scope.1654                        RibKind::Item(has_generic_params, def_kind) => {1655                            (has_generic_params, def_kind)1656                        }1657                    };16581659                    if let Some(span) = finalize {1660                        let item = if let Some(diag_metadata) = diag_metadata1661                            && let Some(current_item) = diag_metadata.current_item1662                        {1663                            let label_span = current_item1664                                .kind1665                                .ident()1666                                .map(|i| i.span)1667                                .unwrap_or(current_item.span);1668                            Some((label_span, current_item.span, current_item.kind.clone()))1669                        } else {1670                            None1671                        };1672                        self.report_error(1673                            span,1674                            ResolutionError::GenericParamsFromOuterItem {1675                                outer_res: res,1676                                has_generic_params,1677                                def_kind,1678                                inner_item: item,1679                                current_self_ty: diag_metadata1680                                    .and_then(|m| m.current_self_type.as_ref())1681                                    .and_then(|ty| {1682                                        self.tcx.sess.source_map().span_to_snippet(ty.span).ok()1683                                    }),1684                            },1685                        );1686                    }1687                    return Res::Err;1688                }1689            }1690            Res::Def(DefKind::ConstParam, _) => {1691                for rib in ribs {1692                    let (has_generic_params, def_kind) = match rib.kind {1693                        RibKind::Normal1694                        | RibKind::Block(..)1695                        | RibKind::FnOrCoroutine1696                        | RibKind::Module(..)1697                        | RibKind::MacroDefinition(..)1698                        | RibKind::InlineAsmSym1699                        | RibKind::AssocItem1700                        | RibKind::ForwardGenericParamBan(_) => continue,17011702                        RibKind::ConstParamTy => {1703                            if !self.features.generic_const_parameter_types() {1704                                if let Some(span) = finalize {1705                                    self.report_error(1706                                        span,1707                                        ResolutionError::ParamInTyOfConstParam {1708                                            name: rib_ident.name,1709                                        },1710                                    );1711                                }1712                                return Res::Err;1713                            } else {1714                                continue;1715                            }1716                        }17171718                        RibKind::ConstantItem(trivial, _) => {1719                            if let ConstantHasGenerics::No(cause) = trivial {1720                                if let Some(span) = finalize {1721                                    let error = match cause {1722                                        NoConstantGenericsReason::IsEnumDiscriminant => {1723                                            ResolutionError::ParamInEnumDiscriminant {1724                                                name: rib_ident.name,1725                                                param_kind: ParamKindInEnumDiscriminant::Const,1726                                            }1727                                        }1728                                        NoConstantGenericsReason::NonTrivialConstArg => {1729                                            ResolutionError::ParamInNonTrivialAnonConst {1730                                                is_gca: self.features.generic_const_args(),1731                                                name: rib_ident.name,1732                                                param_kind: ParamKindInNonTrivialAnonConst::Const {1733                                                    name: rib_ident.name,1734                                                },1735                                            }1736                                        }1737                                    };1738                                    self.report_error(span, error);1739                                }17401741                                return Res::Err;1742                            }17431744                            continue;1745                        }17461747                        RibKind::Item(has_generic_params, def_kind) => {1748                            (has_generic_params, def_kind)1749                        }1750                    };17511752                    // This was an attempt to use a const parameter outside its scope.1753                    if let Some(span) = finalize {1754                        let item = if let Some(diag_metadata) = diag_metadata1755                            && let Some(current_item) = diag_metadata.current_item1756                        {1757                            let label_span = current_item1758                                .kind1759                                .ident()1760                                .map(|i| i.span)1761                                .unwrap_or(current_item.span);1762                            Some((label_span, current_item.span, current_item.kind.clone()))1763                        } else {1764                            None1765                        };1766                        self.report_error(1767                            span,1768                            ResolutionError::GenericParamsFromOuterItem {1769                                outer_res: res,1770                                has_generic_params,1771                                def_kind,1772                                inner_item: item,1773                                current_self_ty: diag_metadata1774                                    .and_then(|m| m.current_self_type.as_ref())1775                                    .and_then(|ty| {1776                                        self.tcx.sess.source_map().span_to_snippet(ty.span).ok()1777                                    }),1778                            },1779                        );1780                    }1781                    return Res::Err;1782                }1783            }1784            _ => {}1785        }17861787        res1788    }17891790    #[instrument(level = "debug", skip(self))]1791    pub(crate) fn maybe_resolve_path<'r>(1792        self: CmResolver<'r, 'ra, 'tcx>,1793        path: &[Segment],1794        opt_ns: Option<Namespace>, // `None` indicates a module path in import1795        parent_scope: &ParentScope<'ra>,1796        ignore_import: Option<Import<'ra>>,1797    ) -> PathResult<'ra> {1798        self.resolve_path_with_ribs(1799            path,1800            opt_ns,1801            parent_scope,1802            None,1803            None,1804            None,1805            None,1806            ignore_import,1807            None,1808        )1809    }1810    #[instrument(level = "debug", skip(self))]1811    pub(crate) fn resolve_path<'r>(1812        self: CmResolver<'r, 'ra, 'tcx>,1813        path: &[Segment],1814        opt_ns: Option<Namespace>, // `None` indicates a module path in import1815        parent_scope: &ParentScope<'ra>,1816        finalize: Option<Finalize>,1817        ignore_decl: Option<Decl<'ra>>,1818        ignore_import: Option<Import<'ra>>,1819    ) -> PathResult<'ra> {1820        self.resolve_path_with_ribs(1821            path,1822            opt_ns,1823            parent_scope,1824            None,1825            finalize,1826            None,1827            ignore_decl,1828            ignore_import,1829            None,1830        )1831    }18321833    pub(crate) fn resolve_path_with_ribs<'r>(1834        mut self: CmResolver<'r, 'ra, 'tcx>,1835        path: &[Segment],1836        opt_ns: Option<Namespace>, // `None` indicates a module path in import1837        parent_scope: &ParentScope<'ra>,1838        source: Option<PathSource<'_, '_, '_>>,1839        finalize: Option<Finalize>,1840        ribs: Option<&PerNS<Vec<Rib<'ra>>>>,1841        ignore_decl: Option<Decl<'ra>>,1842        ignore_import: Option<Import<'ra>>,1843        diag_metadata: Option<&DiagMetadata<'_>>,1844    ) -> PathResult<'ra> {1845        let mut module = None;1846        let mut module_had_parse_errors = !self.mods_with_parse_errors.is_empty()1847            && self1848                .mods_with_parse_errors1849                .contains(&parent_scope.module.nearest_parent_mod().to_def_id());1850        let mut allow_super = true;1851        let mut second_binding = None;18521853        // We'll provide more context to the privacy errors later, up to `len`.1854        let privacy_errors_len = self.privacy_errors.len();1855        fn record_segment_res<'r, 'ra, 'tcx>(1856            mut this: CmResolver<'r, 'ra, 'tcx>,1857            finalize: Option<Finalize>,1858            res: Res,1859            id: Option<NodeId>,1860        ) {1861            if finalize.is_some()1862                && let Some(id) = id1863                && !this.partial_res_map.contains_key(&id)1864            {1865                assert!(id != ast::DUMMY_NODE_ID, "Trying to resolve dummy id");1866                this.get_mut().record_partial_res(id, PartialRes::new(res));1867            }1868        }18691870        for (segment_idx, &Segment { ident, id, .. }) in path.iter().enumerate() {1871            debug!("resolve_path ident {} {:?} {:?}", segment_idx, ident, id);18721873            let is_last = segment_idx + 1 == path.len();1874            let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };1875            let name = ident.name;18761877            allow_super &= ns == TypeNS && (name == kw::SelfLower || name == kw::Super);18781879            if ns == TypeNS {1880                if allow_super && name == kw::Super {1881                    let parent = if segment_idx == 0 {1882                        self.resolve_super_in_module(ident, None, parent_scope)1883                    } else if let Some(ModuleOrUniformRoot::Module(module)) = module {1884                        self.resolve_super_in_module(ident, Some(module), parent_scope)1885                    } else {1886                        None1887                    };1888                    if let Some(parent) = parent {1889                        module = Some(ModuleOrUniformRoot::Module(parent));1890                        continue;1891                    }1892                    let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();1893                    let current_module = self.resolve_self(&mut ctxt, parent_scope.module);1894                    let current_module_path = module_to_string(current_module)1895                        .map_or_else(|| "crate".to_string(), |path| format!("crate::{path}"));1896                    return PathResult::failed(1897                        ident,1898                        false,1899                        finalize.is_some(),1900                        module_had_parse_errors,1901                        module,1902                        || {1903                            (1904                                format!(1905                                    "too many leading `super` keywords within `{current_module_path}`"1906                                ),1907                                "this `super` would go above the crate root".to_string(),1908                                None,1909                                None,1910                            )1911                        },1912                    );1913                }1914                if segment_idx == 0 {1915                    if name == kw::SelfLower {1916                        let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();1917                        let self_mod = self.resolve_self(&mut ctxt, parent_scope.module);1918                        if let Some(res) = self_mod.res() {1919                            record_segment_res(self.reborrow(), finalize, res, id);1920                        }1921                        module = Some(ModuleOrUniformRoot::Module(self_mod));1922                        continue;1923                    }1924                    if name == kw::PathRoot && ident.span.at_least_rust_2018() {1925                        module = Some(ModuleOrUniformRoot::ExternPrelude);1926                        continue;1927                    }1928                    if name == kw::PathRoot1929                        && ident.span.is_rust_2015()1930                        && self.tcx.sess.at_least_rust_2018()1931                    {1932                        // `::a::b` from 2015 macro on 2018 global edition1933                        let crate_root = self.resolve_crate_root(ident);1934                        module = Some(ModuleOrUniformRoot::ModuleAndExternPrelude(crate_root));1935                        continue;1936                    }1937                    if name == kw::PathRoot || name == kw::Crate || name == kw::DollarCrate {1938                        // `::a::b`, `crate::a::b` or `$crate::a::b`1939                        let crate_root = self.resolve_crate_root(ident);1940                        if let Some(res) = crate_root.res() {1941                            record_segment_res(self.reborrow(), finalize, res, id);1942                        }1943                        module = Some(ModuleOrUniformRoot::Module(crate_root));1944                        continue;1945                    }1946                }1947            }19481949            let allow_trailing_self = is_last && name == kw::SelfLower;19501951            // Report special messages for path segment keywords in wrong positions.1952            if ident.is_path_segment_keyword() && segment_idx != 0 && !allow_trailing_self {1953                return PathResult::failed(1954                    ident,1955                    false,1956                    finalize.is_some(),1957                    module_had_parse_errors,1958                    module,1959                    || {1960                        let name_str = if name == kw::PathRoot {1961                            "the crate root".to_string()1962                        } else {1963                            format!("`{name}`")1964                        };1965                        let (message, label) = if segment_idx == 11966                            && path[0].ident.name == kw::PathRoot1967                        {1968                            (1969                                format!("global paths cannot start with {name_str}"),1970                                "cannot start with this".to_string(),1971                            )1972                        } else if name == kw::SelfLower {1973                            (1974                                format!(1975                                    "`self` in paths can only be used in start position or last position"1976                                ),1977                                "can only be used in path start position or last position"1978                                    .to_string(),1979                            )1980                        } else {1981                            (1982                                format!("{name_str} in paths can only be used in start position"),1983                                "can only be used in path start position".to_string(),1984                            )1985                        };1986                        (message, label, None, None)1987                    },1988                );1989            }19901991            let binding = if let Some(module) = module {1992                self.reborrow().resolve_ident_in_module(1993                    module,1994                    ident,1995                    ns,1996                    parent_scope,1997                    finalize,1998                    ignore_decl,1999                    ignore_import,2000                )

Code quality findings 34

Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning correctness unchecked-indexing
Scope::MacroRules(self.invocation_parent_scopes[&invoc_id].macro_rules)
Warning: '.unwrap()' will panic on None/Err variants. Prefer using pattern matching (match, if let), combinators (map, and_then), or the '?' operator for robust error handling.
warning correctness unwrap-usage
return Some((module.parent.unwrap().nearest_item_scope(), None));
Warning: '.unwrap()' will panic on None/Err variants. Prefer using pattern matching (match, if let), combinators (map, and_then), or the '?' operator for robust error handling.
warning correctness unwrap-usage
scope1: Scope::ModuleGlobs(decl.parent_module.unwrap(), None),
Warning: '.unwrap()' will panic on None/Err variants. Prefer using pattern matching (match, if let), combinators (map, and_then), or the '?' operator for robust error handling.
warning correctness unwrap-usage
scope2: Scope::ModuleGlobs(decl.parent_module.unwrap(), None),
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning correctness unchecked-indexing
let (innermost_decl, innermost_scope) = innermost_results[0];
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning correctness unchecked-indexing
&& innermost_results[1..]
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning correctness unchecked-indexing
if innermost_results[1..]
Warning: '.unwrap()' will panic on None/Err variants. Prefer using pattern matching (match, if let), combinators (map, and_then), or the '?' operator for robust error handling.
warning correctness unwrap-usage
return Ok(module.self_decl.unwrap());
Warning: '.unwrap()' will panic on None/Err variants. Prefer using pattern matching (match, if let), combinators (map, and_then), or the '?' operator for robust error handling.
warning correctness unwrap-usage
return Ok(module.self_decl.unwrap());
Warning: '.unwrap()' will panic on None/Err variants. Prefer using pattern matching (match, if let), combinators (map, and_then), or the '?' operator for robust error handling.
warning correctness unwrap-usage
return Ok(module.self_decl.unwrap());
Warning: '.unwrap()' will panic on None/Err variants. Prefer using pattern matching (match, if let), combinators (map, and_then), or the '?' operator for robust error handling.
warning correctness unwrap-usage
return Ok(module.self_decl.unwrap());
Warning: '.unwrap()' will panic on None/Err variants. Prefer using pattern matching (match, if let), combinators (map, and_then), or the '?' operator for robust error handling.
warning correctness unwrap-usage
return Ok(module.self_decl.unwrap());
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning correctness unchecked-indexing
} else if decls[ns].get().decl().is_none() && binding.is_some() {
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning correctness unchecked-indexing
let ribs = &all_ribs[rib_index + 1..];
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning correctness unchecked-indexing
if let RibKind::ForwardGenericParamBan(reason) = all_ribs[rib_index].kind {
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning correctness unchecked-indexing
&& path[0].ident.name == kw::PathRoot
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning correctness unchecked-indexing
&ribs[ns],
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning correctness unchecked-indexing
for error in &mut self.get_mut().privacy_errors[privacy_errors_len..] {
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning correctness unchecked-indexing
let scope = match &path[..segment_idx] {
Warning: '.unwrap()' will panic on None/Err variants. Prefer using pattern matching (match, if let), combinators (map, and_then), or the '?' operator for robust error handling.
warning correctness unwrap-usage
module.res().unwrap(),
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info maintainability wildcard-import
use Determinacy::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info maintainability wildcard-import
use Namespace::*;
Info: Ensure 'match' statements are exhaustive. If matching on enums, consider adding a wildcard arm `_ => {}` only if necessary and intentional, as it suppresses warnings about unhandled variants.
info correctness match-wildcard
let mut scope = match ns {
Info: Ensure 'match' statements are exhaustive. If matching on enums, consider adding a wildcard arm `_ => {}` only if necessary and intentional, as it suppresses warnings about unhandled variants.
info correctness match-wildcard
let visit = match scope {
Info: Ensure 'match' statements are exhaustive. If matching on enums, consider adding a wildcard arm `_ => {}` only if necessary and intentional, as it suppresses warnings about unhandled variants.
info correctness match-wildcard
scope = match scope {
Info: Ensure 'match' statements are exhaustive. If matching on enums, consider adding a wildcard arm `_ => {}` only if necessary and intentional, as it suppresses warnings about unhandled variants.
info correctness match-wildcard
match expn_data.kind {
Info: Ensure 'match' statements are exhaustive. If matching on enums, consider adding a wildcard arm `_ => {}` only if necessary and intentional, as it suppresses warnings about unhandled variants.
info correctness match-wildcard
Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() {
Info: Ensure 'match' statements are exhaustive. If matching on enums, consider adding a wildcard arm `_ => {}` only if necessary and intentional, as it suppresses warnings about unhandled variants.
info correctness match-wildcard
Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() {
Info: Ensure 'match' statements are exhaustive. If matching on enums, consider adding a wildcard arm `_ => {}` only if necessary and intentional, as it suppresses warnings about unhandled variants.
info correctness match-wildcard
let issue_149681_hack = match scope {
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info maintainability wildcard-import
use ResolutionError::*;
Info: Ensure 'match' statements are exhaustive. If matching on enums, consider adding a wildcard arm `_ => {}` only if necessary and intentional, as it suppresses warnings about unhandled variants.
info correctness match-wildcard
error.source = match source {
Performance Info: Frequent cloning, especially of Strings, Vecs, or other heap-allocated types inside loops, can be expensive. Consider using references/borrowing where possible.
info performance clone-in-loop
| Some(PathSource::Expr(Some(expr))) => Some(expr.clone()),
Info: Ensure 'match' statements are exhaustive. If matching on enums, consider adding a wildcard arm `_ => {}` only if necessary and intentional, as it suppresses warnings about unhandled variants.
info correctness match-wildcard
let scope = match &path[..segment_idx] {
Info: Ensure 'match' statements are exhaustive. If matching on enums, consider adding a wildcard arm `_ => {}` only if necessary and intentional, as it suppresses warnings about unhandled variants.
info correctness match-wildcard
PathResult::Module(match module {

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.