File is large — showing lines 1–2,000 of 2,120.
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_middle::{bug, span_bug};9use rustc_session::errors::feature_err;10use rustc_session::lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK;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::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};18use crate::hygiene::Macros20NormalizedSyntaxContext;19use crate::imports::{Import, NameResolution};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, Finalize, IdentKey, ImportKind, ImportSummary, LateDecl, LocalModule, Module,27 ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError, Res, ResolutionError,28 Resolver, Scope, ScopeSet, Segment, Stage, Symbol, Used, errors,29};3031#[derive(Copy, Clone)]32pub enum UsePrelude {33 No,34 Yes,35}3637impl From<UsePrelude> for bool {38 fn from(up: UsePrelude) -> bool {39 matches!(up, UsePrelude::Yes)40 }41}4243#[derive(Debug, PartialEq, Clone, Copy)]44enum Shadowing {45 Restricted,46 Unrestricted,47}4849impl<'ra, 'tcx> Resolver<'ra, 'tcx> {50 /// A generic scope visitor.51 /// Visits scopes in order to resolve some identifier in them or perform other actions.52 /// If the callback returns `Some` result, we stop visiting scopes and return it.53 pub(crate) fn visit_scopes<'r, T>(54 mut self: CmResolver<'r, 'ra, 'tcx>,55 scope_set: ScopeSet<'ra>,56 parent_scope: &ParentScope<'ra>,57 mut ctxt: Macros20NormalizedSyntaxContext,58 orig_ident_span: Span,59 derive_fallback_lint_id: Option<NodeId>,60 mut visitor: impl FnMut(61 CmResolver<'_, 'ra, 'tcx>,62 Scope<'ra>,63 UsePrelude,64 Macros20NormalizedSyntaxContext,65 ) -> ControlFlow<T>,66 ) -> Option<T> {67 // General principles:68 // 1. Not controlled (user-defined) names should have higher priority than controlled names69 // built into the language or standard library. This way we can add new names into the70 // language or standard library without breaking user code.71 // 2. "Closed set" below means new names cannot appear after the current resolution attempt.72 // Places to search (in order of decreasing priority):73 // (Type NS)74 // 1. FIXME: Ribs (type parameters), there's no necessary infrastructure yet75 // (open set, not controlled).76 // 2. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents77 // (open, not controlled).78 // 3. Extern prelude (open, the open part is from macro expansions, not controlled).79 // 4. Tool modules (closed, controlled right now, but not in the future).80 // 5. Standard library prelude (de-facto closed, controlled).81 // 6. Language prelude (closed, controlled).82 // (Value NS)83 // 1. FIXME: Ribs (local variables), there's no necessary infrastructure yet84 // (open set, not controlled).85 // 2. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents86 // (open, not controlled).87 // 3. Standard library prelude (de-facto closed, controlled).88 // (Macro NS)89 // 1-3. Derive helpers (open, not controlled). All ambiguities with other names90 // are currently reported as errors. They should be higher in priority than preludes91 // and probably even names in modules according to the "general principles" above. They92 // also should be subject to restricted shadowing because are effectively produced by93 // derives (you need to resolve the derive first to add helpers into scope), but they94 // should be available before the derive is expanded for compatibility.95 // It's mess in general, so we are being conservative for now.96 // 1-3. `macro_rules` (open, not controlled), loop through `macro_rules` scopes. Have higher97 // priority than prelude macros, but create ambiguities with macros in modules.98 // 1-3. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents99 // (open, not controlled). Have higher priority than prelude macros, but create100 // ambiguities with `macro_rules`.101 // 4. `macro_use` prelude (open, the open part is from macro expansions, not controlled).102 // 4a. User-defined prelude from macro-use103 // (open, the open part is from macro expansions, not controlled).104 // 4b. "Standard library prelude" part implemented through `macro-use` (closed, controlled).105 // 4c. Standard library prelude (de-facto closed, controlled).106 // 6. Language prelude: builtin attributes (closed, controlled).107108 let (ns, macro_kind) = match scope_set {109 ScopeSet::All(ns)110 | ScopeSet::Module(ns, _)111 | ScopeSet::ModuleAndExternPrelude(ns, _) => (ns, None),112 ScopeSet::ExternPrelude => (TypeNS, None),113 ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),114 };115 let module = match scope_set {116 // Start with the specified module.117 ScopeSet::Module(_, module) | ScopeSet::ModuleAndExternPrelude(_, module) => module,118 // Jump out of trait or enum modules, they do not act as scopes.119 _ => parent_scope.module.nearest_item_scope(),120 };121 let module_only = matches!(scope_set, ScopeSet::Module(..));122 let module_and_extern_prelude = matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..));123 let extern_prelude = matches!(scope_set, ScopeSet::ExternPrelude);124 let mut scope = match ns {125 _ if module_only || module_and_extern_prelude => Scope::ModuleNonGlobs(module, None),126 _ if extern_prelude => Scope::ExternPreludeItems,127 TypeNS | ValueNS => Scope::ModuleNonGlobs(module, None),128 MacroNS => Scope::DeriveHelpers(parent_scope.expansion),129 };130 let mut use_prelude = !module.no_implicit_prelude;131132 loop {133 let visit = match scope {134 // Derive helpers are not in scope when resolving derives in the same container.135 Scope::DeriveHelpers(expn_id) => {136 !(expn_id == parent_scope.expansion && macro_kind == Some(MacroKind::Derive))137 }138 Scope::DeriveHelpersCompat => true,139 Scope::MacroRules(macro_rules_scope) => {140 // Use "path compression" on `macro_rules` scope chains. This is an optimization141 // used to avoid long scope chains, see the comments on `MacroRulesScopeRef`.142 // As another consequence of this optimization visitors never observe invocation143 // scopes for macros that were already expanded.144 while let MacroRulesScope::Invocation(invoc_id) = macro_rules_scope.get() {145 if let Some(next_scope) = self.output_macro_rules_scopes.get(&invoc_id) {146 macro_rules_scope.set(next_scope.get());147 } else {148 break;149 }150 }151 true152 }153 Scope::ModuleNonGlobs(..) | Scope::ModuleGlobs(..) => true,154 Scope::MacroUsePrelude => use_prelude || orig_ident_span.is_rust_2015(),155 Scope::BuiltinAttrs => true,156 Scope::ExternPreludeItems | Scope::ExternPreludeFlags => {157 use_prelude || module_and_extern_prelude || extern_prelude158 }159 Scope::ToolPrelude => use_prelude,160 Scope::StdLibPrelude => use_prelude || ns == MacroNS,161 Scope::BuiltinTypes => true,162 };163164 if visit {165 let use_prelude = if use_prelude { UsePrelude::Yes } else { UsePrelude::No };166 if let ControlFlow::Break(break_result) =167 visitor(self.reborrow(), scope, use_prelude, ctxt)168 {169 return Some(break_result);170 }171 }172173 scope = match scope {174 Scope::DeriveHelpers(LocalExpnId::ROOT) => Scope::DeriveHelpersCompat,175 Scope::DeriveHelpers(expn_id) => {176 // Derive helpers are not visible to code generated by bang or derive macros.177 let expn_data = expn_id.expn_data();178 match expn_data.kind {179 ExpnKind::Root180 | ExpnKind::Macro(MacroKind::Bang | MacroKind::Derive, _) => {181 Scope::DeriveHelpersCompat182 }183 _ => Scope::DeriveHelpers(expn_data.parent.expect_local()),184 }185 }186 Scope::DeriveHelpersCompat => Scope::MacroRules(parent_scope.macro_rules),187 Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() {188 MacroRulesScope::Def(binding) => {189 Scope::MacroRules(binding.parent_macro_rules_scope)190 }191 MacroRulesScope::Invocation(invoc_id) => {192 Scope::MacroRules(self.invocation_parent_scopes[&invoc_id].macro_rules)193 }194 MacroRulesScope::Empty => Scope::ModuleNonGlobs(module, None),195 },196 Scope::ModuleNonGlobs(module, lint_id) => Scope::ModuleGlobs(module, lint_id),197 Scope::ModuleGlobs(..) if module_only => break,198 Scope::ModuleGlobs(..) if module_and_extern_prelude => match ns {199 TypeNS => {200 ctxt.update_unchecked(|ctxt| ctxt.adjust(ExpnId::root()));201 Scope::ExternPreludeItems202 }203 ValueNS | MacroNS => break,204 },205 Scope::ModuleGlobs(module, prev_lint_id) => {206 use_prelude = !module.no_implicit_prelude;207 match self.hygienic_lexical_parent(module, &mut ctxt, derive_fallback_lint_id) {208 Some((parent_module, lint_id)) => {209 Scope::ModuleNonGlobs(parent_module, lint_id.or(prev_lint_id))210 }211 None => {212 ctxt.update_unchecked(|ctxt| ctxt.adjust(ExpnId::root()));213 match ns {214 TypeNS => Scope::ExternPreludeItems,215 ValueNS => Scope::StdLibPrelude,216 MacroNS => Scope::MacroUsePrelude,217 }218 }219 }220 }221 Scope::MacroUsePrelude => Scope::StdLibPrelude,222 Scope::BuiltinAttrs => break, // nowhere else to search223 Scope::ExternPreludeItems => Scope::ExternPreludeFlags,224 Scope::ExternPreludeFlags if module_and_extern_prelude || extern_prelude => break,225 Scope::ExternPreludeFlags => Scope::ToolPrelude,226 Scope::ToolPrelude => Scope::StdLibPrelude,227 Scope::StdLibPrelude => match ns {228 TypeNS => Scope::BuiltinTypes,229 ValueNS => break, // nowhere else to search230 MacroNS => Scope::BuiltinAttrs,231 },232 Scope::BuiltinTypes => break, // nowhere else to search233 };234 }235236 None237 }238239 fn hygienic_lexical_parent(240 &self,241 module: Module<'ra>,242 ctxt: &mut Macros20NormalizedSyntaxContext,243 derive_fallback_lint_id: Option<NodeId>,244 ) -> Option<(Module<'ra>, Option<NodeId>)> {245 if !module.expansion.outer_expn_is_descendant_of(**ctxt) {246 let expn_id = ctxt.update_unchecked(|ctxt| ctxt.remove_mark());247 return Some((self.expn_def_scope(expn_id), None));248 }249250 if let ModuleKind::Block = module.kind {251 return Some((module.parent.unwrap().nearest_item_scope(), None));252 }253254 // We need to support the next case under a deprecation warning255 // ```256 // struct MyStruct;257 // ---- begin: this comes from a proc macro derive258 // mod implementation_details {259 // // Note that `MyStruct` is not in scope here.260 // impl SomeTrait for MyStruct { ... }261 // }262 // ---- end263 // ```264 // So we have to fall back to the module's parent during lexical resolution in this case.265 if derive_fallback_lint_id.is_some()266 && let Some(parent) = module.parent267 // Inner module is inside the macro268 && module.expansion != parent.expansion269 // Parent module is outside of the macro270 && module.expansion.is_descendant_of(parent.expansion)271 // The macro is a proc macro derive272 && let Some(def_id) = module.expansion.expn_data().macro_def_id273 {274 let ext = &self.get_macro_by_def_id(def_id).ext;275 if ext.builtin_name.is_none()276 && ext.macro_kinds() == MacroKinds::DERIVE277 && parent.expansion.outer_expn_is_descendant_of(**ctxt)278 {279 return Some((parent, derive_fallback_lint_id));280 }281 }282283 None284 }285286 /// This resolves the identifier `ident` in the namespace `ns` in the current lexical scope.287 /// More specifically, we proceed up the hierarchy of scopes and return the binding for288 /// `ident` in the first scope that defines it (or None if no scopes define it).289 ///290 /// A block's items are above its local variables in the scope hierarchy, regardless of where291 /// the items are defined in the block. For example,292 /// ```rust293 /// fn f() {294 /// g(); // Since there are no local variables in scope yet, this resolves to the item.295 /// let g = || {};296 /// fn g() {}297 /// g(); // This resolves to the local variable `g` since it shadows the item.298 /// }299 /// ```300 ///301 /// Invariant: This must only be called during main resolution, not during302 /// import resolution.303 #[instrument(level = "debug", skip(self, ribs))]304 pub(crate) fn resolve_ident_in_lexical_scope(305 &mut self,306 mut ident: Ident,307 ns: Namespace,308 parent_scope: &ParentScope<'ra>,309 finalize: Option<Finalize>,310 ribs: &[Rib<'ra>],311 ignore_decl: Option<Decl<'ra>>,312 diag_metadata: Option<&DiagMetadata<'_>>,313 ) -> Option<LateDecl<'ra>> {314 let orig_ident = ident;315 let (general_span, normalized_span) = if ident.name == kw::SelfUpper {316 // FIXME(jseyfried) improve `Self` hygiene317 let empty_span = ident.span.with_ctxt(SyntaxContext::root());318 (empty_span, empty_span)319 } else if ns == TypeNS {320 let normalized_span = ident.span.normalize_to_macros_2_0();321 (normalized_span, normalized_span)322 } else {323 (ident.span.normalize_to_macro_rules(), ident.span.normalize_to_macros_2_0())324 };325 ident.span = general_span;326 let normalized_ident = Ident { span: normalized_span, ..ident };327328 // Walk backwards up the ribs in scope.329 for (i, rib) in ribs.iter().enumerate().rev() {330 debug!("walk rib\n{:?}", rib.bindings);331 // Use the rib kind to determine whether we are resolving parameters332 // (macro 2.0 hygiene) or local variables (`macro_rules` hygiene).333 let rib_ident = if rib.kind.contains_params() { normalized_ident } else { ident };334 if let Some((original_rib_ident_def, res)) = rib.bindings.get_key_value(&rib_ident) {335 // The ident resolves to a type parameter or local variable.336 return Some(LateDecl::RibDef(self.validate_res_from_ribs(337 i,338 rib_ident,339 *res,340 finalize.map(|_| general_span),341 *original_rib_ident_def,342 ribs,343 diag_metadata,344 )));345 } else if let RibKind::Block(Some(module)) = rib.kind346 && let Ok(binding) = self.cm().resolve_ident_in_scope_set(347 ident,348 ScopeSet::Module(ns, module.to_module()),349 parent_scope,350 finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }),351 ignore_decl,352 None,353 )354 {355 // The ident resolves to an item in a block.356 return Some(LateDecl::Decl(binding));357 } else if let RibKind::Module(module) = rib.kind {358 // Encountered a module item, abandon ribs and look into that module and preludes.359 let parent_scope = &ParentScope { module: module.to_module(), ..*parent_scope };360 let finalize = finalize.map(|f| Finalize { stage: Stage::Late, ..f });361 return self362 .cm()363 .resolve_ident_in_scope_set(364 orig_ident,365 ScopeSet::All(ns),366 parent_scope,367 finalize,368 ignore_decl,369 None,370 )371 .ok()372 .map(LateDecl::Decl);373 }374375 if let RibKind::MacroDefinition(def) = rib.kind376 && def == self.macro_def(ident.span.ctxt())377 {378 // If an invocation of this macro created `ident`, give up on `ident`379 // and switch to `ident`'s source from the macro definition.380 ident.span.remove_mark();381 }382 }383384 unreachable!()385 }386387 /// Resolve an identifier in the specified set of scopes.388 pub(crate) fn resolve_ident_in_scope_set<'r>(389 self: CmResolver<'r, 'ra, 'tcx>,390 orig_ident: Ident,391 scope_set: ScopeSet<'ra>,392 parent_scope: &ParentScope<'ra>,393 finalize: Option<Finalize>,394 ignore_decl: Option<Decl<'ra>>,395 ignore_import: Option<Import<'ra>>,396 ) -> Result<Decl<'ra>, Determinacy> {397 self.resolve_ident_in_scope_set_inner(398 IdentKey::new(orig_ident),399 orig_ident.span,400 scope_set,401 parent_scope,402 finalize,403 ignore_decl,404 ignore_import,405 )406 }407408 fn resolve_ident_in_scope_set_inner<'r>(409 self: CmResolver<'r, 'ra, 'tcx>,410 ident: IdentKey,411 orig_ident_span: Span,412 scope_set: ScopeSet<'ra>,413 parent_scope: &ParentScope<'ra>,414 finalize: Option<Finalize>,415 ignore_decl: Option<Decl<'ra>>,416 ignore_import: Option<Import<'ra>>,417 ) -> Result<Decl<'ra>, Determinacy> {418 // Make sure `self`, `super` etc produce an error when passed to here.419 if !matches!(scope_set, ScopeSet::Module(..)) && ident.name.is_path_segment_keyword() {420 return Err(Determinacy::Determined);421 }422423 let (ns, macro_kind) = match scope_set {424 ScopeSet::All(ns)425 | ScopeSet::Module(ns, _)426 | ScopeSet::ModuleAndExternPrelude(ns, _) => (ns, None),427 ScopeSet::ExternPrelude => (TypeNS, None),428 ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),429 };430 let derive_fallback_lint_id = match finalize {431 Some(Finalize { node_id, stage: Stage::Late, .. }) => Some(node_id),432 _ => None,433 };434435 // This is *the* result, resolution from the scope closest to the resolved identifier.436 // However, sometimes this result is "weak" because it comes from a glob import or437 // a macro expansion, and in this case it cannot shadow names from outer scopes, e.g.438 // mod m { ... } // solution in outer scope439 // {440 // use prefix::*; // imports another `m` - innermost solution441 // // weak, cannot shadow the outer `m`, need to report ambiguity error442 // m::mac!();443 // }444 // So we have to save the innermost solution and continue searching in outer scopes445 // to detect potential ambiguities.446 let mut innermost_results: SmallVec<[(Decl<'_>, Scope<'_>); 2]> = SmallVec::new();447 let mut determinacy = Determinacy::Determined;448449 // Go through all the scopes and try to resolve the name.450 let break_result = self.visit_scopes(451 scope_set,452 parent_scope,453 ident.ctxt,454 orig_ident_span,455 derive_fallback_lint_id,456 |mut this, scope, use_prelude, ctxt| {457 let ident = IdentKey { name: ident.name, ctxt };458 let res = match this.reborrow().resolve_ident_in_scope(459 ident,460 orig_ident_span,461 ns,462 scope,463 use_prelude,464 scope_set,465 parent_scope,466 // Shadowed decls don't need to be marked as used or non-speculatively loaded.467 if innermost_results.is_empty() { finalize } else { None },468 ignore_decl,469 ignore_import,470 ) {471 Ok(decl) => Ok(decl),472 // We can break with an error at this step, it means we cannot determine the473 // resolution right now, but we must block and wait until we can, instead of474 // considering outer scopes. Although there's no need to do that if we already475 // have a better solution.476 Err(ControlFlow::Break(determinacy)) if innermost_results.is_empty() => {477 return ControlFlow::Break(Err(determinacy));478 }479 Err(determinacy) => Err(determinacy.into_value()),480 };481 match res {482 Ok(decl) if sub_namespace_match(decl.macro_kinds(), macro_kind) => {483 // Below we report various ambiguity errors.484 // We do not need to report them if we are either in speculative resolution,485 // or in late resolution when everything is already imported and expanded486 // and no ambiguities exist.487 let import = match finalize {488 None | Some(Finalize { stage: Stage::Late, .. }) => {489 return ControlFlow::Break(Ok(decl));490 }491 Some(Finalize { import, .. }) => import,492 };493 this.get_mut().maybe_push_glob_vs_glob_vis_ambiguity(494 ident,495 orig_ident_span,496 decl,497 import,498 );499500 if let Some(&(innermost_decl, _)) = innermost_results.first() {501 // Found another solution, if the first one was "weak", report an error.502 if this.get_mut().maybe_push_ambiguity(503 ident,504 orig_ident_span,505 ns,506 scope_set,507 parent_scope,508 decl,509 scope,510 &innermost_results,511 import,512 ) {513 // No need to search for more potential ambiguities, one is enough.514 return ControlFlow::Break(Ok(innermost_decl));515 }516 }517518 innermost_results.push((decl, scope));519 }520 Ok(_) | Err(Determinacy::Determined) => {}521 Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined,522 }523524 ControlFlow::Continue(())525 },526 );527528 // Scope visiting returned some result early.529 if let Some(break_result) = break_result {530 return break_result;531 }532533 // Scope visiting walked all the scopes and maybe found something in one of them.534 match innermost_results.first() {535 Some(&(decl, ..)) => Ok(decl),536 None => Err(determinacy),537 }538 }539540 fn resolve_ident_in_scope<'r>(541 mut self: CmResolver<'r, 'ra, 'tcx>,542 ident: IdentKey,543 orig_ident_span: Span,544 ns: Namespace,545 scope: Scope<'ra>,546 use_prelude: UsePrelude,547 scope_set: ScopeSet<'ra>,548 parent_scope: &ParentScope<'ra>,549 finalize: Option<Finalize>,550 ignore_decl: Option<Decl<'ra>>,551 ignore_import: Option<Import<'ra>>,552 ) -> Result<Decl<'ra>, ControlFlow<Determinacy, Determinacy>> {553 let ret = match scope {554 Scope::DeriveHelpers(expn_id) => {555 if let Some(decl) = self556 .helper_attrs557 .get(&expn_id)558 .and_then(|attrs| attrs.iter().rfind(|(i, ..)| ident == *i).map(|(.., d)| *d))559 {560 Ok(decl)561 } else {562 Err(Determinacy::Determined)563 }564 }565 Scope::DeriveHelpersCompat => {566 let mut result = Err(Determinacy::Determined);567 for derive in parent_scope.derives {568 let parent_scope = &ParentScope { derives: &[], ..*parent_scope };569 match self.reborrow().resolve_derive_macro_path(570 derive,571 parent_scope,572 false,573 ignore_import,574 ) {575 Ok((Some(ext), _)) => {576 if ext.helper_attrs.contains(&ident.name) {577 let decl = self.arenas.new_pub_def_decl(578 Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat),579 derive.span,580 LocalExpnId::ROOT,581 );582 result = Ok(decl);583 break;584 }585 }586 Ok(_) | Err(Determinacy::Determined) => {}587 Err(Determinacy::Undetermined) => result = Err(Determinacy::Undetermined),588 }589 }590 result591 }592 Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() {593 MacroRulesScope::Def(macro_rules_def) if ident == macro_rules_def.ident => {594 Ok(macro_rules_def.decl)595 }596 MacroRulesScope::Invocation(_) => Err(Determinacy::Undetermined),597 _ => Err(Determinacy::Determined),598 },599 Scope::ModuleNonGlobs(module, derive_fallback_lint_id) => {600 let (adjusted_parent_scope, adjusted_finalize) = if matches!(601 scope_set,602 ScopeSet::Module(..) | ScopeSet::ModuleAndExternPrelude(..)603 ) {604 (parent_scope, finalize)605 } else {606 (607 &ParentScope { module, ..*parent_scope },608 finalize.map(|f| Finalize { used: Used::Scope, ..f }),609 )610 };611 let decl = self.reborrow().resolve_ident_in_module_non_globs_unadjusted(612 module,613 ident,614 orig_ident_span,615 ns,616 adjusted_parent_scope,617 if matches!(scope_set, ScopeSet::Module(..)) {618 Shadowing::Unrestricted619 } else {620 Shadowing::Restricted621 },622 adjusted_finalize,623 ignore_decl,624 ignore_import,625 );626 match decl {627 Ok(decl) => {628 if let Some(lint_id) = derive_fallback_lint_id {629 self.get_mut().lint_buffer.buffer_lint(630 PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,631 lint_id,632 orig_ident_span,633 errors::ProcMacroDeriveResolutionFallback {634 span: orig_ident_span,635 ns_descr: ns.descr(),636 ident: ident.name,637 },638 );639 }640 Ok(decl)641 }642 Err(ControlFlow::Continue(determinacy)) => Err(determinacy),643 Err(ControlFlow::Break(..)) => return decl,644 }645 }646 Scope::ModuleGlobs(module, _)647 if let ModuleKind::Def(_, def_id, _, _) = module.kind648 && !def_id.is_local() =>649 {650 // Fast path: external module decoding only creates non-glob declarations.651 Err(Determined)652 }653 Scope::ModuleGlobs(module, derive_fallback_lint_id) => {654 let (adjusted_parent_scope, adjusted_finalize) = if matches!(655 scope_set,656 ScopeSet::Module(..) | ScopeSet::ModuleAndExternPrelude(..)657 ) {658 (parent_scope, finalize)659 } else {660 (661 &ParentScope { module, ..*parent_scope },662 finalize.map(|f| Finalize { used: Used::Scope, ..f }),663 )664 };665 let binding = self.reborrow().resolve_ident_in_module_globs_unadjusted(666 module.expect_local(),667 ident,668 orig_ident_span,669 ns,670 adjusted_parent_scope,671 if matches!(scope_set, ScopeSet::Module(..)) {672 Shadowing::Unrestricted673 } else {674 Shadowing::Restricted675 },676 adjusted_finalize,677 ignore_decl,678 ignore_import,679 );680 match binding {681 Ok(binding) => {682 if let Some(lint_id) = derive_fallback_lint_id {683 self.get_mut().lint_buffer.buffer_lint(684 PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,685 lint_id,686 orig_ident_span,687 errors::ProcMacroDeriveResolutionFallback {688 span: orig_ident_span,689 ns_descr: ns.descr(),690 ident: ident.name,691 },692 );693 }694 Ok(binding)695 }696 Err(ControlFlow::Continue(determinacy)) => Err(determinacy),697 Err(ControlFlow::Break(..)) => return binding,698 }699 }700 Scope::MacroUsePrelude => match self.macro_use_prelude.get(&ident.name).cloned() {701 Some(decl) => Ok(decl),702 None => Err(Determinacy::determined(703 self.graph_root.unexpanded_invocations.borrow().is_empty(),704 )),705 },706 Scope::BuiltinAttrs => match self.builtin_attr_decls.get(&ident.name) {707 Some(decl) => Ok(*decl),708 None => Err(Determinacy::Determined),709 },710 Scope::ExternPreludeItems => {711 match self.reborrow().extern_prelude_get_item(712 ident,713 orig_ident_span,714 finalize.is_some(),715 ) {716 Some(decl) => Ok(decl),717 None => Err(Determinacy::determined(718 self.graph_root.unexpanded_invocations.borrow().is_empty(),719 )),720 }721 }722 Scope::ExternPreludeFlags => {723 match self.extern_prelude_get_flag(ident, orig_ident_span, finalize.is_some()) {724 Some(decl) => Ok(decl),725 None => Err(Determinacy::Determined),726 }727 }728 Scope::ToolPrelude => match self.registered_tool_decls.get(&ident) {729 Some(decl) => Ok(*decl),730 None => Err(Determinacy::Determined),731 },732 Scope::StdLibPrelude => {733 let mut result = Err(Determinacy::Determined);734 if let Some(prelude) = self.prelude735 && let Ok(decl) = self.reborrow().resolve_ident_in_scope_set_inner(736 ident,737 orig_ident_span,738 ScopeSet::Module(ns, prelude),739 parent_scope,740 None,741 ignore_decl,742 ignore_import,743 )744 && (matches!(use_prelude, UsePrelude::Yes) || self.is_builtin_macro(decl.res()))745 {746 result = Ok(decl)747 }748749 result750 }751 Scope::BuiltinTypes => match self.builtin_type_decls.get(&ident.name) {752 Some(decl) => {753 if matches!(ident.name, sym::f16)754 && !self.tcx.features().f16()755 && !orig_ident_span.allows_unstable(sym::f16)756 && finalize.is_some()757 {758 feature_err(759 self.tcx.sess,760 sym::f16,761 orig_ident_span,762 "the type `f16` is unstable",763 )764 .emit();765 }766 if matches!(ident.name, sym::f128)767 && !self.tcx.features().f128()768 && !orig_ident_span.allows_unstable(sym::f128)769 && finalize.is_some()770 {771 feature_err(772 self.tcx.sess,773 sym::f128,774 orig_ident_span,775 "the type `f128` is unstable",776 )777 .emit();778 }779 Ok(*decl)780 }781 None => Err(Determinacy::Determined),782 },783 };784785 ret.map_err(ControlFlow::Continue)786 }787788 fn maybe_push_glob_vs_glob_vis_ambiguity(789 &mut self,790 ident: IdentKey,791 orig_ident_span: Span,792 decl: Decl<'ra>,793 import: Option<ImportSummary>,794 ) {795 let Some(import) = import else { return };796 let vis1 = self.import_decl_vis(decl, import);797 let vis2 = self.import_decl_vis_ext(decl, import, true);798 if vis1 != vis2 {799 self.ambiguity_errors.push(AmbiguityError {800 kind: AmbiguityKind::GlobVsGlob,801 ambig_vis: Some((vis1, vis2)),802 ident: ident.orig(orig_ident_span),803 b1: decl.ambiguity_vis_max.get().unwrap_or(decl),804 b2: decl.ambiguity_vis_min.get().unwrap_or(decl),805 scope1: Scope::ModuleGlobs(decl.parent_module.unwrap(), None),806 scope2: Scope::ModuleGlobs(decl.parent_module.unwrap(), None),807 warning: Some(AmbiguityWarning::GlobImport),808 });809 }810 }811812 fn maybe_push_ambiguity(813 &mut self,814 ident: IdentKey,815 orig_ident_span: Span,816 ns: Namespace,817 scope_set: ScopeSet<'ra>,818 parent_scope: &ParentScope<'ra>,819 decl: Decl<'ra>,820 scope: Scope<'ra>,821 innermost_results: &[(Decl<'ra>, Scope<'ra>)],822 import: Option<ImportSummary>,823 ) -> bool {824 let (innermost_decl, innermost_scope) = innermost_results[0];825 let (res, innermost_res) = (decl.res(), innermost_decl.res());826 let ambig_vis = if res != innermost_res {827 None828 } else if let Some(import) = import829 && let vis1 = self.import_decl_vis(decl, import)830 && let vis2 = self.import_decl_vis(innermost_decl, import)831 && vis1 != vis2832 {833 Some((vis1, vis2))834 } else {835 return false;836 };837838 // FIXME: Use `scope` instead of `res` to detect built-in attrs and derive helpers,839 // it will exclude imports, make slightly more code legal, and will require lang approval.840 let module_only = matches!(scope_set, ScopeSet::Module(..));841 let is_builtin = |res| matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Builtin(..)));842 let derive_helper = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);843 let derive_helper_compat = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat);844845 let ambiguity_error_kind = if is_builtin(innermost_res) || is_builtin(res) {846 Some(AmbiguityKind::BuiltinAttr)847 } else if innermost_res == derive_helper_compat {848 Some(AmbiguityKind::DeriveHelper)849 } else if res == derive_helper_compat && innermost_res != derive_helper {850 span_bug!(orig_ident_span, "impossible inner resolution kind")851 } else if matches!(innermost_scope, Scope::MacroRules(_))852 && matches!(scope, Scope::ModuleNonGlobs(..) | Scope::ModuleGlobs(..))853 && !self.disambiguate_macro_rules_vs_modularized(innermost_decl, decl)854 {855 Some(AmbiguityKind::MacroRulesVsModularized)856 } else if matches!(scope, Scope::MacroRules(_))857 && matches!(innermost_scope, Scope::ModuleNonGlobs(..) | Scope::ModuleGlobs(..))858 {859 // should be impossible because of visitation order in860 // visit_scopes861 //862 // we visit all macro_rules scopes (e.g. textual scope macros)863 // before we visit any modules (e.g. path-based scope macros)864 span_bug!(865 orig_ident_span,866 "ambiguous scoped macro resolutions with path-based \867 scope resolution as first candidate"868 )869 } else if innermost_decl.is_glob_import() {870 Some(AmbiguityKind::GlobVsOuter)871 } else if !module_only && innermost_decl.may_appear_after(parent_scope.expansion, decl) {872 Some(AmbiguityKind::MoreExpandedVsOuter)873 } else if innermost_decl.expansion != LocalExpnId::ROOT874 && (!module_only || ns == MacroNS)875 && let Scope::ModuleGlobs(m1, _) = scope876 && let Scope::ModuleNonGlobs(m2, _) = innermost_scope877 && m1 == m2878 {879 // FIXME: this error is too conservative and technically unnecessary now when module880 // scope is split into two scopes, at least when not resolving in `ScopeSet::Module`,881 // remove it with lang team approval.882 Some(AmbiguityKind::GlobVsExpanded)883 } else {884 None885 };886887 if let Some(kind) = ambiguity_error_kind {888 // Skip ambiguity errors for extern flag bindings "overridden"889 // by extern item bindings.890 // FIXME: Remove with lang team approval.891 let issue_145575_hack = matches!(scope, Scope::ExternPreludeFlags)892 && innermost_results[1..]893 .iter()894 .any(|(b, s)| matches!(s, Scope::ExternPreludeItems) && *b != innermost_decl);895 // Skip ambiguity errors for nonglob module bindings "overridden"896 // by glob module bindings in the same module.897 // FIXME: Remove with lang team approval.898 let issue_149681_hack = match scope {899 Scope::ModuleGlobs(m1, _)900 if innermost_results[1..]901 .iter()902 .any(|(_, s)| matches!(*s, Scope::ModuleNonGlobs(m2, _) if m1 == m2)) =>903 {904 true905 }906 _ => false,907 };908909 if issue_145575_hack || issue_149681_hack {910 self.issue_145575_hack_applied = true;911 } else {912 // Turn ambiguity errors for core vs std panic into warnings.913 // FIXME: Remove with lang team approval.914 let is_issue_147319_hack = orig_ident_span.edition() <= Edition::Edition2024915 && matches!(ident.name, sym::panic)916 && matches!(scope, Scope::StdLibPrelude)917 && matches!(innermost_scope, Scope::ModuleGlobs(_, _))918 && ((self.is_specific_builtin_macro(res, sym::std_panic)919 && self.is_specific_builtin_macro(innermost_res, sym::core_panic))920 || (self.is_specific_builtin_macro(res, sym::core_panic)921 && self.is_specific_builtin_macro(innermost_res, sym::std_panic)));922923 let warning = if ambig_vis.is_some() {924 Some(AmbiguityWarning::GlobImport)925 } else if is_issue_147319_hack {926 Some(AmbiguityWarning::PanicImport)927 } else {928 None929 };930931 self.ambiguity_errors.push(AmbiguityError {932 kind,933 ambig_vis,934 ident: ident.orig(orig_ident_span),935 b1: innermost_decl,936 b2: decl,937 scope1: innermost_scope,938 scope2: scope,939 warning,940 });941 return true;942 }943 }944945 false946 }947948 #[instrument(level = "debug", skip(self))]949 pub(crate) fn maybe_resolve_ident_in_module<'r>(950 self: CmResolver<'r, 'ra, 'tcx>,951 module: ModuleOrUniformRoot<'ra>,952 ident: Ident,953 ns: Namespace,954 parent_scope: &ParentScope<'ra>,955 ignore_import: Option<Import<'ra>>,956 ) -> Result<Decl<'ra>, Determinacy> {957 self.resolve_ident_in_module(module, ident, ns, parent_scope, None, None, ignore_import)958 }959960 fn resolve_super_in_module(961 &self,962 ident: Ident,963 module: Option<Module<'ra>>,964 parent_scope: &ParentScope<'ra>,965 ) -> Option<Module<'ra>> {966 let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();967 module968 .unwrap_or_else(|| self.resolve_self(&mut ctxt, parent_scope.module))969 .parent970 .map(|parent| self.resolve_self(&mut ctxt, parent))971 }972973 pub(crate) fn path_root_is_crate_root(&self, ident: Ident) -> bool {974 ident.name == kw::PathRoot && ident.span.is_rust_2015() && self.tcx.sess.is_rust_2015()975 }976977 #[instrument(level = "debug", skip(self))]978 pub(crate) fn resolve_ident_in_module<'r>(979 self: CmResolver<'r, 'ra, 'tcx>,980 module: ModuleOrUniformRoot<'ra>,981 ident: Ident,982 ns: Namespace,983 parent_scope: &ParentScope<'ra>,984 finalize: Option<Finalize>,985 ignore_decl: Option<Decl<'ra>>,986 ignore_import: Option<Import<'ra>>,987 ) -> Result<Decl<'ra>, Determinacy> {988 match module {989 ModuleOrUniformRoot::Module(module) => {990 if ns == TypeNS {991 if ident.name == kw::SelfLower {992 return Ok(module.self_decl.unwrap());993 }994 if ident.name == kw::Super995 && let Some(module) =996 self.resolve_super_in_module(ident, Some(module), parent_scope)997 {998 return Ok(module.self_decl.unwrap());999 }1000 }10011002 let (ident_key, def) = IdentKey::new_adjusted(ident, module.expansion);1003 let adjusted_parent_scope = match def {1004 Some(def) => ParentScope { module: self.expn_def_scope(def), ..*parent_scope },1005 None => *parent_scope,1006 };1007 self.resolve_ident_in_scope_set_inner(1008 ident_key,1009 ident.span,1010 ScopeSet::Module(ns, module),1011 &adjusted_parent_scope,1012 finalize,1013 ignore_decl,1014 ignore_import,1015 )1016 }1017 ModuleOrUniformRoot::OpenModule(sym) => {1018 let open_ns_name = format!("{}::{}", sym.as_str(), ident.name);1019 let ns_ident = IdentKey::with_root_ctxt(Symbol::intern(&open_ns_name));1020 match self.extern_prelude_get_flag(ns_ident, ident.span, finalize.is_some()) {1021 Some(decl) => Ok(decl),1022 None => Err(Determinacy::Determined),1023 }1024 }1025 ModuleOrUniformRoot::ModuleAndExternPrelude(module) => self.resolve_ident_in_scope_set(1026 ident,1027 ScopeSet::ModuleAndExternPrelude(ns, module),1028 parent_scope,1029 finalize,1030 ignore_decl,1031 ignore_import,1032 ),1033 ModuleOrUniformRoot::ExternPrelude => {1034 if ns != TypeNS {1035 Err(Determined)1036 } else {1037 self.resolve_ident_in_scope_set_inner(1038 IdentKey::new_adjusted(ident, ExpnId::root()).0,1039 ident.span,1040 ScopeSet::ExternPrelude,1041 parent_scope,1042 finalize,1043 ignore_decl,1044 ignore_import,1045 )1046 }1047 }1048 ModuleOrUniformRoot::CurrentScope => {1049 if ns == TypeNS {1050 if ident.name == kw::SelfLower {1051 let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();1052 let module = self.resolve_self(&mut ctxt, parent_scope.module);1053 return Ok(module.self_decl.unwrap());1054 }1055 if ident.name == kw::Super1056 && let Some(module) =1057 self.resolve_super_in_module(ident, None, parent_scope)1058 {1059 return Ok(module.self_decl.unwrap());1060 }1061 if ident.name == kw::Crate1062 || ident.name == kw::DollarCrate1063 || self.path_root_is_crate_root(ident)1064 {1065 let module = self.resolve_crate_root(ident);1066 return Ok(module.self_decl.unwrap());1067 } else if ident.name == kw::Super {1068 // FIXME: Implement these with renaming requirements so that e.g.1069 // `use super;` doesn't work, but `use super as name;` does.1070 // Fall through here to get an error from `early_resolve_...`.1071 }1072 }10731074 self.resolve_ident_in_scope_set(1075 ident,1076 ScopeSet::All(ns),1077 parent_scope,1078 finalize,1079 ignore_decl,1080 ignore_import,1081 )1082 }1083 }1084 }10851086 /// Attempts to resolve `ident` in namespace `ns` of non-glob bindings in `module`.1087 fn resolve_ident_in_module_non_globs_unadjusted<'r>(1088 mut self: CmResolver<'r, 'ra, 'tcx>,1089 module: Module<'ra>,1090 ident: IdentKey,1091 orig_ident_span: Span,1092 ns: Namespace,1093 parent_scope: &ParentScope<'ra>,1094 shadowing: Shadowing,1095 finalize: Option<Finalize>,1096 // This binding should be ignored during in-module resolution, so that we don't get1097 // "self-confirming" import resolutions during import validation and checking.1098 ignore_decl: Option<Decl<'ra>>,1099 ignore_import: Option<Import<'ra>>,1100 ) -> Result<Decl<'ra>, ControlFlow<Determinacy, Determinacy>> {1101 let key = BindingKey::new(ident, ns);1102 // `try_borrow_mut` is required to ensure exclusive access, even if the resulting binding1103 // doesn't need to be mutable. It will fail when there is a cycle of imports, and without1104 // the exclusive access infinite recursion will crash the compiler with stack overflow.1105 let resolution = &*self1106 .resolution_or_default(module, key, orig_ident_span)1107 .try_borrow_mut_unchecked()1108 .map_err(|_| ControlFlow::Continue(Determined))?;11091110 let binding = resolution.non_glob_decl.filter(|b| Some(*b) != ignore_decl);11111112 if let Some(finalize) = finalize {1113 return self.get_mut().finalize_module_binding(1114 ident,1115 orig_ident_span,1116 binding,1117 parent_scope,1118 finalize,1119 shadowing,1120 );1121 }11221123 // Items and single imports are not shadowable, if we have one, then it's determined.1124 if let Some(binding) = binding {1125 let accessible = self.is_accessible_from(binding.vis(), parent_scope.module);1126 return if accessible { Ok(binding) } else { Err(ControlFlow::Break(Determined)) };1127 }11281129 // Check if one of single imports can still define the name, block if it can.1130 if self.reborrow().single_import_can_define_name(1131 &resolution,1132 None,1133 ns,1134 ignore_import,1135 ignore_decl,1136 parent_scope,1137 ) {1138 return Err(ControlFlow::Break(Undetermined));1139 }11401141 // Check if one of unexpanded macros can still define the name.1142 if !module.unexpanded_invocations.borrow().is_empty() {1143 return Err(ControlFlow::Continue(Undetermined));1144 }11451146 // No resolution and no one else can define the name - determinate error.1147 Err(ControlFlow::Continue(Determined))1148 }11491150 /// Attempts to resolve `ident` in namespace `ns` of glob bindings in `module`.1151 fn resolve_ident_in_module_globs_unadjusted<'r>(1152 mut self: CmResolver<'r, 'ra, 'tcx>,1153 module: LocalModule<'ra>,1154 ident: IdentKey,1155 orig_ident_span: Span,1156 ns: Namespace,1157 parent_scope: &ParentScope<'ra>,1158 shadowing: Shadowing,1159 finalize: Option<Finalize>,1160 ignore_decl: Option<Decl<'ra>>,1161 ignore_import: Option<Import<'ra>>,1162 ) -> Result<Decl<'ra>, ControlFlow<Determinacy, Determinacy>> {1163 let key = BindingKey::new(ident, ns);1164 // `try_borrow_mut` is required to ensure exclusive access, even if the resulting binding1165 // doesn't need to be mutable. It will fail when there is a cycle of imports, and without1166 // the exclusive access infinite recursion will crash the compiler with stack overflow.1167 let resolution = &*self1168 .resolution_or_default(module.to_module(), key, orig_ident_span)1169 .try_borrow_mut_unchecked()1170 .map_err(|_| ControlFlow::Continue(Determined))?;11711172 let binding = resolution.glob_decl.filter(|b| Some(*b) != ignore_decl);11731174 if let Some(finalize) = finalize {1175 return self.get_mut().finalize_module_binding(1176 ident,1177 orig_ident_span,1178 binding,1179 parent_scope,1180 finalize,1181 shadowing,1182 );1183 }11841185 // Check if one of single imports can still define the name,1186 // if it can then our result is not determined and can be invalidated.1187 if self.reborrow().single_import_can_define_name(1188 &resolution,1189 binding,1190 ns,1191 ignore_import,1192 ignore_decl,1193 parent_scope,1194 ) {1195 return Err(ControlFlow::Break(Undetermined));1196 }11971198 // So we have a resolution that's from a glob import. This resolution is determined1199 // if it cannot be shadowed by some new item/import expanded from a macro.1200 // This happens either if there are no unexpanded macros, or expanded names cannot1201 // shadow globs (that happens in macro namespace or with restricted shadowing).1202 //1203 // Additionally, any macro in any module can plant names in the root module if it creates1204 // `macro_export` macros, so the root module effectively has unresolved invocations if any1205 // module has unresolved invocations.1206 // However, it causes resolution/expansion to stuck too often (#53144), so, to make1207 // progress, we have to ignore those potential unresolved invocations from other modules1208 // and prohibit access to macro-expanded `macro_export` macros instead (unless restricted1209 // shadowing is enabled, see `macro_expanded_macro_export_errors`).1210 if let Some(binding) = binding {1211 return if binding.determined() || ns == MacroNS || shadowing == Shadowing::Restricted {1212 let accessible = self.is_accessible_from(binding.vis(), parent_scope.module);1213 if accessible { Ok(binding) } else { Err(ControlFlow::Break(Determined)) }1214 } else {1215 Err(ControlFlow::Break(Undetermined))1216 };1217 }12181219 // Now we are in situation when new item/import can appear only from a glob or a macro1220 // expansion. With restricted shadowing names from globs and macro expansions cannot1221 // shadow names from outer scopes, so we can freely fallback from module search to search1222 // in outer scopes. For `resolve_ident_in_scope_set` to continue search in outer1223 // scopes we return `Undetermined` with `ControlFlow::Continue`.1224 // Check if one of unexpanded macros can still define the name,1225 // if it can then our "no resolution" result is not determined and can be invalidated.1226 if !module.unexpanded_invocations.borrow().is_empty() {1227 return Err(ControlFlow::Continue(Undetermined));1228 }12291230 // Check if one of glob imports can still define the name,1231 // if it can then our "no resolution" result is not determined and can be invalidated.1232 for glob_import in module.globs.borrow().iter() {1233 if ignore_import == Some(*glob_import) {1234 continue;1235 }1236 if !self.is_accessible_from(glob_import.vis, parent_scope.module) {1237 continue;1238 }1239 let module = match glob_import.imported_module.get() {1240 Some(ModuleOrUniformRoot::Module(module)) => module,1241 Some(_) => continue,1242 None => return Err(ControlFlow::Continue(Undetermined)),1243 };1244 let tmp_parent_scope;1245 let (mut adjusted_parent_scope, mut adjusted_ident) = (parent_scope, ident);1246 match adjusted_ident1247 .ctxt1248 .update_unchecked(|ctxt| ctxt.glob_adjust(module.expansion, glob_import.span))1249 {1250 Some(Some(def)) => {1251 tmp_parent_scope =1252 ParentScope { module: self.expn_def_scope(def), ..*parent_scope };1253 adjusted_parent_scope = &tmp_parent_scope;1254 }1255 Some(None) => {}1256 None => continue,1257 };1258 let result = self.reborrow().resolve_ident_in_scope_set_inner(1259 adjusted_ident,1260 orig_ident_span,1261 ScopeSet::Module(ns, module),1262 adjusted_parent_scope,1263 None,1264 ignore_decl,1265 ignore_import,1266 );12671268 match result {1269 Err(Determined) => continue,1270 Ok(binding)1271 if !self.is_accessible_from(binding.vis(), glob_import.parent_scope.module) =>1272 {1273 continue;1274 }1275 Ok(_) | Err(Undetermined) => return Err(ControlFlow::Continue(Undetermined)),1276 }1277 }12781279 // No resolution and no one else can define the name - determinate error.1280 Err(ControlFlow::Continue(Determined))1281 }12821283 fn finalize_module_binding(1284 &mut self,1285 ident: IdentKey,1286 orig_ident_span: Span,1287 binding: Option<Decl<'ra>>,1288 parent_scope: &ParentScope<'ra>,1289 finalize: Finalize,1290 shadowing: Shadowing,1291 ) -> Result<Decl<'ra>, ControlFlow<Determinacy, Determinacy>> {1292 let Finalize { path_span, report_private, used, root_span, .. } = finalize;12931294 let Some(binding) = binding else {1295 return Err(ControlFlow::Continue(Determined));1296 };12971298 let ident = ident.orig(orig_ident_span);1299 if !self.is_accessible_from(binding.vis(), parent_scope.module) {1300 if report_private {1301 self.privacy_errors.push(PrivacyError {1302 ident,1303 decl: binding,1304 dedup_span: path_span,1305 outermost_res: None,1306 source: None,1307 parent_scope: *parent_scope,1308 single_nested: path_span != root_span,1309 });1310 } else {1311 return Err(ControlFlow::Break(Determined));1312 }1313 }13141315 if shadowing == Shadowing::Unrestricted1316 && binding.expansion != LocalExpnId::ROOT1317 && let DeclKind::Import { import, .. } = binding.kind1318 && matches!(import.kind, ImportKind::MacroExport)1319 {1320 self.macro_expanded_macro_export_errors.insert((path_span, binding.span));1321 }13221323 self.record_use(ident, binding, used);1324 return Ok(binding);1325 }13261327 // Checks if a single import can define the `Ident` corresponding to `binding`.1328 // This is used to check whether we can definitively accept a glob as a resolution.1329 fn single_import_can_define_name<'r>(1330 mut self: CmResolver<'r, 'ra, 'tcx>,1331 resolution: &NameResolution<'ra>,1332 binding: Option<Decl<'ra>>,1333 ns: Namespace,1334 ignore_import: Option<Import<'ra>>,1335 ignore_decl: Option<Decl<'ra>>,1336 parent_scope: &ParentScope<'ra>,1337 ) -> bool {1338 for single_import in &resolution.single_imports {1339 if let Some(decl) = resolution.non_glob_decl1340 && let DeclKind::Import { import, .. } = decl.kind1341 && import == *single_import1342 {1343 // Single import has already defined the name and we are aware of it,1344 // no need to block the globs.1345 continue;1346 }1347 if ignore_import == Some(*single_import) {1348 continue;1349 }1350 if !self.is_accessible_from(single_import.vis, parent_scope.module) {1351 continue;1352 }1353 if let Some(ignored) = ignore_decl1354 && let DeclKind::Import { import, .. } = ignored.kind1355 && import == *single_import1356 {1357 continue;1358 }13591360 let Some(module) = single_import.imported_module.get() else {1361 return true;1362 };1363 let ImportKind::Single { source, target, decls, .. } = &single_import.kind else {1364 unreachable!();1365 };1366 if source != target {1367 if decls.iter().all(|d| d.get().decl().is_none()) {1368 return true;1369 } else if decls[ns].get().decl().is_none() && binding.is_some() {1370 return true;1371 }1372 }13731374 match self.reborrow().resolve_ident_in_module(1375 module,1376 *source,1377 ns,1378 &single_import.parent_scope,1379 None,1380 ignore_decl,1381 None,1382 ) {1383 Err(Determined) => continue,1384 Ok(binding)1385 if !self1386 .is_accessible_from(binding.vis(), single_import.parent_scope.module) =>1387 {1388 continue;1389 }1390 Ok(_) | Err(Undetermined) => return true,1391 }1392 }13931394 false1395 }13961397 /// Validate a local resolution (from ribs).1398 #[instrument(level = "debug", skip(self, all_ribs))]1399 fn validate_res_from_ribs(1400 &mut self,1401 rib_index: usize,1402 rib_ident: Ident,1403 res: Res,1404 finalize: Option<Span>,1405 original_rib_ident_def: Ident,1406 all_ribs: &[Rib<'ra>],1407 diag_metadata: Option<&DiagMetadata<'_>>,1408 ) -> Res {1409 debug!("validate_res_from_ribs({:?})", res);1410 let ribs = &all_ribs[rib_index + 1..];14111412 // An invalid forward use of a generic parameter from a previous default1413 // or in a const param ty.1414 if let RibKind::ForwardGenericParamBan(reason) = all_ribs[rib_index].kind {1415 if let Some(span) = finalize {1416 let res_error = if rib_ident.name == kw::SelfUpper {1417 ResolutionError::ForwardDeclaredSelf(reason)1418 } else {1419 ResolutionError::ForwardDeclaredGenericParam(rib_ident.name, reason)1420 };1421 self.report_error(span, res_error);1422 }1423 assert_eq!(res, Res::Err);1424 return Res::Err;1425 }14261427 match res {1428 Res::Local(_) => {1429 use ResolutionError::*;1430 let mut res_err = None;14311432 for rib in ribs {1433 match rib.kind {1434 RibKind::Normal1435 | RibKind::Block(..)1436 | RibKind::FnOrCoroutine1437 | RibKind::Module(..)1438 | RibKind::MacroDefinition(..)1439 | RibKind::ForwardGenericParamBan(_) => {1440 // Nothing to do. Continue.1441 }1442 RibKind::Item(..) | RibKind::AssocItem => {1443 // This was an attempt to access an upvar inside a1444 // named function item. This is not allowed, so we1445 // report an error.1446 if let Some(span) = finalize {1447 // We don't immediately trigger a resolve error, because1448 // we want certain other resolution errors (namely those1449 // emitted for `ConstantItemRibKind` below) to take1450 // precedence.1451 res_err = Some((span, CannotCaptureDynamicEnvironmentInFnItem));1452 }1453 }1454 RibKind::ConstantItem(_, item) => {1455 // Still doesn't deal with upvars1456 if let Some(span) = finalize {1457 let (span, resolution_error) = match item {1458 None if rib_ident.name == kw::SelfLower => {1459 (span, LowercaseSelf)1460 }1461 None => {1462 // If we have a `let name = expr;`, we have the span for1463 // `name` and use that to see if it is followed by a type1464 // specifier. If not, then we know we need to suggest1465 // `const name: Ty = expr;`. This is a heuristic, it will1466 // break down in the presence of macros.1467 let sm = self.tcx.sess.source_map();1468 let type_span = match sm1469 .span_followed_by(original_rib_ident_def.span, ":")1470 {1471 None => {1472 Some(original_rib_ident_def.span.shrink_to_hi())1473 }1474 Some(_) => None,1475 };1476 (1477 rib_ident.span,1478 AttemptToUseNonConstantValueInConstant {1479 ident: original_rib_ident_def,1480 suggestion: "const",1481 current: "let",1482 type_span,1483 },1484 )1485 }1486 Some((ident, kind)) => (1487 span,1488 AttemptToUseNonConstantValueInConstant {1489 ident,1490 suggestion: "let",1491 current: kind.as_str(),1492 type_span: None,1493 },1494 ),1495 };1496 self.report_error(span, resolution_error);1497 }1498 return Res::Err;1499 }1500 RibKind::ConstParamTy => {1501 if let Some(span) = finalize {1502 self.report_error(1503 span,1504 ParamInTyOfConstParam { name: rib_ident.name },1505 );1506 }1507 return Res::Err;1508 }1509 RibKind::InlineAsmSym => {1510 if let Some(span) = finalize {1511 self.report_error(span, InvalidAsmSym);1512 }1513 return Res::Err;1514 }1515 }1516 }1517 if let Some((span, res_err)) = res_err {1518 self.report_error(span, res_err);1519 return Res::Err;1520 }1521 }1522 Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {1523 for rib in ribs {1524 let (has_generic_params, def_kind) = match rib.kind {1525 RibKind::Normal1526 | RibKind::Block(..)1527 | RibKind::FnOrCoroutine1528 | RibKind::Module(..)1529 | RibKind::MacroDefinition(..)1530 | RibKind::InlineAsmSym1531 | RibKind::AssocItem1532 | RibKind::ForwardGenericParamBan(_) => {1533 // Nothing to do. Continue.1534 continue;1535 }15361537 RibKind::ConstParamTy => {1538 if !self.tcx.features().generic_const_parameter_types() {1539 if let Some(span) = finalize {1540 self.report_error(1541 span,1542 ResolutionError::ParamInTyOfConstParam {1543 name: rib_ident.name,1544 },1545 );1546 }1547 return Res::Err;1548 } else {1549 continue;1550 }1551 }15521553 RibKind::ConstantItem(trivial, _) => {1554 if let ConstantHasGenerics::No(cause) = trivial1555 && !matches!(res, Res::SelfTyAlias { .. })1556 {1557 if let Some(span) = finalize {1558 let error = match cause {1559 NoConstantGenericsReason::IsEnumDiscriminant => {1560 ResolutionError::ParamInEnumDiscriminant {1561 name: rib_ident.name,1562 param_kind: ParamKindInEnumDiscriminant::Type,1563 }1564 }1565 NoConstantGenericsReason::NonTrivialConstArg => {1566 ResolutionError::ParamInNonTrivialAnonConst {1567 is_gca: self.tcx.features().generic_const_args(),1568 name: rib_ident.name,1569 param_kind: ParamKindInNonTrivialAnonConst::Type,1570 }1571 }1572 };1573 let _: ErrorGuaranteed = self.report_error(span, error);1574 }15751576 return Res::Err;1577 }15781579 continue;1580 }15811582 // This was an attempt to use a type parameter outside its scope.1583 RibKind::Item(has_generic_params, def_kind) => {1584 (has_generic_params, def_kind)1585 }1586 };15871588 if let Some(span) = finalize {1589 let item = if let Some(diag_metadata) = diag_metadata1590 && let Some(current_item) = diag_metadata.current_item1591 {1592 let label_span = current_item1593 .kind1594 .ident()1595 .map(|i| i.span)1596 .unwrap_or(current_item.span);1597 Some((label_span, current_item.span, current_item.kind.clone()))1598 } else {1599 None1600 };1601 self.report_error(1602 span,1603 ResolutionError::GenericParamsFromOuterItem {1604 outer_res: res,1605 has_generic_params,1606 def_kind,1607 inner_item: item,1608 current_self_ty: diag_metadata1609 .and_then(|m| m.current_self_type.as_ref())1610 .and_then(|ty| {1611 self.tcx.sess.source_map().span_to_snippet(ty.span).ok()1612 }),1613 },1614 );1615 }1616 return Res::Err;1617 }1618 }1619 Res::Def(DefKind::ConstParam, _) => {1620 for rib in ribs {1621 let (has_generic_params, def_kind) = match rib.kind {1622 RibKind::Normal1623 | RibKind::Block(..)1624 | RibKind::FnOrCoroutine1625 | RibKind::Module(..)1626 | RibKind::MacroDefinition(..)1627 | RibKind::InlineAsmSym1628 | RibKind::AssocItem1629 | RibKind::ForwardGenericParamBan(_) => continue,16301631 RibKind::ConstParamTy => {1632 if !self.tcx.features().generic_const_parameter_types() {1633 if let Some(span) = finalize {1634 self.report_error(1635 span,1636 ResolutionError::ParamInTyOfConstParam {1637 name: rib_ident.name,1638 },1639 );1640 }1641 return Res::Err;1642 } else {1643 continue;1644 }1645 }16461647 RibKind::ConstantItem(trivial, _) => {1648 if let ConstantHasGenerics::No(cause) = trivial {1649 if let Some(span) = finalize {1650 let error = match cause {1651 NoConstantGenericsReason::IsEnumDiscriminant => {1652 ResolutionError::ParamInEnumDiscriminant {1653 name: rib_ident.name,1654 param_kind: ParamKindInEnumDiscriminant::Const,1655 }1656 }1657 NoConstantGenericsReason::NonTrivialConstArg => {1658 ResolutionError::ParamInNonTrivialAnonConst {1659 is_gca: self.tcx.features().generic_const_args(),1660 name: rib_ident.name,1661 param_kind: ParamKindInNonTrivialAnonConst::Const {1662 name: rib_ident.name,1663 },1664 }1665 }1666 };1667 self.report_error(span, error);1668 }16691670 return Res::Err;1671 }16721673 continue;1674 }16751676 RibKind::Item(has_generic_params, def_kind) => {1677 (has_generic_params, def_kind)1678 }1679 };16801681 // This was an attempt to use a const parameter outside its scope.1682 if let Some(span) = finalize {1683 let item = if let Some(diag_metadata) = diag_metadata1684 && let Some(current_item) = diag_metadata.current_item1685 {1686 let label_span = current_item1687 .kind1688 .ident()1689 .map(|i| i.span)1690 .unwrap_or(current_item.span);1691 Some((label_span, current_item.span, current_item.kind.clone()))1692 } else {1693 None1694 };1695 self.report_error(1696 span,1697 ResolutionError::GenericParamsFromOuterItem {1698 outer_res: res,1699 has_generic_params,1700 def_kind,1701 inner_item: item,1702 current_self_ty: diag_metadata1703 .and_then(|m| m.current_self_type.as_ref())1704 .and_then(|ty| {1705 self.tcx.sess.source_map().span_to_snippet(ty.span).ok()1706 }),1707 },1708 );1709 }1710 return Res::Err;1711 }1712 }1713 _ => {}1714 }17151716 res1717 }17181719 #[instrument(level = "debug", skip(self))]1720 pub(crate) fn maybe_resolve_path<'r>(1721 self: CmResolver<'r, 'ra, 'tcx>,1722 path: &[Segment],1723 opt_ns: Option<Namespace>, // `None` indicates a module path in import1724 parent_scope: &ParentScope<'ra>,1725 ignore_import: Option<Import<'ra>>,1726 ) -> PathResult<'ra> {1727 self.resolve_path_with_ribs(1728 path,1729 opt_ns,1730 parent_scope,1731 None,1732 None,1733 None,1734 None,1735 ignore_import,1736 None,1737 )1738 }1739 #[instrument(level = "debug", skip(self))]1740 pub(crate) fn resolve_path<'r>(1741 self: CmResolver<'r, 'ra, 'tcx>,1742 path: &[Segment],1743 opt_ns: Option<Namespace>, // `None` indicates a module path in import1744 parent_scope: &ParentScope<'ra>,1745 finalize: Option<Finalize>,1746 ignore_decl: Option<Decl<'ra>>,1747 ignore_import: Option<Import<'ra>>,1748 ) -> PathResult<'ra> {1749 self.resolve_path_with_ribs(1750 path,1751 opt_ns,1752 parent_scope,1753 None,1754 finalize,1755 None,1756 ignore_decl,1757 ignore_import,1758 None,1759 )1760 }17611762 pub(crate) fn resolve_path_with_ribs<'r>(1763 mut self: CmResolver<'r, 'ra, 'tcx>,1764 path: &[Segment],1765 opt_ns: Option<Namespace>, // `None` indicates a module path in import1766 parent_scope: &ParentScope<'ra>,1767 source: Option<PathSource<'_, '_, '_>>,1768 finalize: Option<Finalize>,1769 ribs: Option<&PerNS<Vec<Rib<'ra>>>>,1770 ignore_decl: Option<Decl<'ra>>,1771 ignore_import: Option<Import<'ra>>,1772 diag_metadata: Option<&DiagMetadata<'_>>,1773 ) -> PathResult<'ra> {1774 let mut module = None;1775 let mut module_had_parse_errors = !self.mods_with_parse_errors.is_empty()1776 && self.mods_with_parse_errors.contains(&parent_scope.module.nearest_parent_mod());1777 let mut allow_super = true;1778 let mut second_binding = None;17791780 // We'll provide more context to the privacy errors later, up to `len`.1781 let privacy_errors_len = self.privacy_errors.len();1782 fn record_segment_res<'r, 'ra, 'tcx>(1783 mut this: CmResolver<'r, 'ra, 'tcx>,1784 finalize: Option<Finalize>,1785 res: Res,1786 id: Option<NodeId>,1787 ) {1788 if finalize.is_some()1789 && let Some(id) = id1790 && !this.partial_res_map.contains_key(&id)1791 {1792 assert!(id != ast::DUMMY_NODE_ID, "Trying to resolve dummy id");1793 this.get_mut().record_partial_res(id, PartialRes::new(res));1794 }1795 }17961797 for (segment_idx, &Segment { ident, id, .. }) in path.iter().enumerate() {1798 debug!("resolve_path ident {} {:?} {:?}", segment_idx, ident, id);17991800 let is_last = segment_idx + 1 == path.len();1801 let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };1802 let name = ident.name;18031804 allow_super &= ns == TypeNS && (name == kw::SelfLower || name == kw::Super);18051806 if ns == TypeNS {1807 if allow_super && name == kw::Super {1808 let parent = if segment_idx == 0 {1809 self.resolve_super_in_module(ident, None, parent_scope)1810 } else if let Some(ModuleOrUniformRoot::Module(module)) = module {1811 self.resolve_super_in_module(ident, Some(module), parent_scope)1812 } else {1813 None1814 };1815 if let Some(parent) = parent {1816 module = Some(ModuleOrUniformRoot::Module(parent));1817 continue;1818 }1819 return PathResult::failed(1820 ident,1821 false,1822 finalize.is_some(),1823 module_had_parse_errors,1824 module,1825 || {1826 (1827 "too many leading `super` keywords".to_string(),1828 "there are too many leading `super` keywords".to_string(),1829 None,1830 None,1831 )1832 },1833 );1834 }1835 if segment_idx == 0 {1836 if name == kw::SelfLower {1837 let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();1838 let self_mod = self.resolve_self(&mut ctxt, parent_scope.module);1839 if let Some(res) = self_mod.res() {1840 record_segment_res(self.reborrow(), finalize, res, id);1841 }1842 module = Some(ModuleOrUniformRoot::Module(self_mod));1843 continue;1844 }1845 if name == kw::PathRoot && ident.span.at_least_rust_2018() {1846 module = Some(ModuleOrUniformRoot::ExternPrelude);1847 continue;1848 }1849 if name == kw::PathRoot1850 && ident.span.is_rust_2015()1851 && self.tcx.sess.at_least_rust_2018()1852 {1853 // `::a::b` from 2015 macro on 2018 global edition1854 let crate_root = self.resolve_crate_root(ident);1855 module = Some(ModuleOrUniformRoot::ModuleAndExternPrelude(crate_root));1856 continue;1857 }1858 if name == kw::PathRoot || name == kw::Crate || name == kw::DollarCrate {1859 // `::a::b`, `crate::a::b` or `$crate::a::b`1860 let crate_root = self.resolve_crate_root(ident);1861 if let Some(res) = crate_root.res() {1862 record_segment_res(self.reborrow(), finalize, res, id);1863 }1864 module = Some(ModuleOrUniformRoot::Module(crate_root));1865 continue;1866 }1867 }1868 }18691870 let allow_trailing_self = is_last && name == kw::SelfLower;18711872 // Report special messages for path segment keywords in wrong positions.1873 if ident.is_path_segment_keyword() && segment_idx != 0 && !allow_trailing_self {1874 return PathResult::failed(1875 ident,1876 false,1877 finalize.is_some(),1878 module_had_parse_errors,1879 module,1880 || {1881 let name_str = if name == kw::PathRoot {1882 "the crate root".to_string()1883 } else {1884 format!("`{name}`")1885 };1886 let (message, label) = if segment_idx == 11887 && path[0].ident.name == kw::PathRoot1888 {1889 (1890 format!("global paths cannot start with {name_str}"),1891 "cannot start with this".to_string(),1892 )1893 } else if name == kw::SelfLower {1894 (1895 format!(1896 "`self` in paths can only be used in start position or last position"1897 ),1898 "can only be used in path start position or last position"1899 .to_string(),1900 )1901 } else {1902 (1903 format!("{name_str} in paths can only be used in start position"),1904 "can only be used in path start position".to_string(),1905 )1906 };1907 (message, label, None, None)1908 },1909 );1910 }19111912 let binding = if let Some(module) = module {1913 self.reborrow().resolve_ident_in_module(1914 module,1915 ident,1916 ns,1917 parent_scope,1918 finalize,1919 ignore_decl,1920 ignore_import,1921 )1922 } else if let Some(ribs) = ribs1923 && let Some(TypeNS | ValueNS) = opt_ns1924 {1925 assert!(ignore_import.is_none());1926 match self.get_mut().resolve_ident_in_lexical_scope(1927 ident,1928 ns,1929 parent_scope,1930 finalize,1931 &ribs[ns],1932 ignore_decl,1933 diag_metadata,1934 ) {1935 // we found a locally-imported or available item/module1936 Some(LateDecl::Decl(binding)) => Ok(binding),1937 // we found a local variable or type param1938 Some(LateDecl::RibDef(res)) => {1939 record_segment_res(self.reborrow(), finalize, res, id);1940 return PathResult::NonModule(PartialRes::with_unresolved_segments(1941 res,1942 path.len() - 1,1943 ));1944 }1945 _ => Err(Determinacy::determined(finalize.is_some())),1946 }1947 } else {1948 self.reborrow().resolve_ident_in_scope_set(1949 ident,1950 ScopeSet::All(ns),1951 parent_scope,1952 finalize,1953 ignore_decl,1954 ignore_import,1955 )1956 };19571958 match binding {1959 Ok(binding) => {1960 if segment_idx == 1 {1961 second_binding = Some(binding);1962 }1963 let res = binding.res();19641965 // Mark every privacy error in this path with the res to the last element. This allows us1966 // to detect the item the user cares about and either find an alternative import, or tell1967 // the user it is not accessible.1968 if finalize.is_some() {1969 for error in &mut self.get_mut().privacy_errors[privacy_errors_len..] {1970 error.outermost_res = Some((res, ident));1971 error.source = match source {1972 Some(PathSource::Struct(Some(expr)))1973 | Some(PathSource::Expr(Some(expr))) => Some(expr.clone()),1974 _ => None,1975 };1976 }1977 }19781979 let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(res);1980 if let Res::OpenMod(sym) = binding.res() {1981 module = Some(ModuleOrUniformRoot::OpenModule(sym));1982 record_segment_res(self.reborrow(), finalize, res, id);1983 } else if let Some(def_id) = binding.res().module_like_def_id() {1984 if self.mods_with_parse_errors.contains(&def_id) {1985 module_had_parse_errors = true;1986 }1987 module = Some(ModuleOrUniformRoot::Module(self.expect_module(def_id)));1988 record_segment_res(self.reborrow(), finalize, res, id);1989 } else if res == Res::ToolMod && !is_last && opt_ns.is_some() {1990 if binding.is_import() {1991 self.dcx().emit_err(errors::ToolModuleImported {1992 span: ident.span,1993 import: binding.span,1994 });1995 }1996 let res = Res::NonMacroAttr(NonMacroAttrKind::Tool);1997 return PathResult::NonModule(PartialRes::new(res));1998 } else if res == Res::Err {1999 return PathResult::NonModule(PartialRes::new(Res::Err));2000 } else if opt_ns.is_some() && (is_last || maybe_assoc) {