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 )