rustc_resolve/ident.rs
1use Determinacy::*;
2use Namespace::*;
3use rustc_ast::{self as ast, NodeId};
4use rustc_errors::ErrorGuaranteed;
5use rustc_hir::def::{DefKind, Namespace, NonMacroAttrKind, PartialRes, PerNS};
6use rustc_middle::{bug, ty};
7use rustc_session::lint::BuiltinLintDiag;
8use rustc_session::lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK;
9use rustc_session::parse::feature_err;
10use rustc_span::def_id::LocalDefId;
11use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext};
12use rustc_span::{Ident, Span, kw, sym};
13use tracing::{debug, instrument};
14
15use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
16use crate::imports::Import;
17use crate::late::{ConstantHasGenerics, NoConstantGenericsReason, PathSource, Rib, RibKind};
18use crate::macros::{MacroRulesScope, sub_namespace_match};
19use crate::{
20 AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingKey, Determinacy, Finalize,
21 ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot, NameBinding,
22 NameBindingKind, ParentScope, PathResult, PrivacyError, Res, ResolutionError, Resolver, Scope,
23 ScopeSet, Segment, ToNameBinding, Used, Weak, errors,
24};
25
26type Visibility = ty::Visibility<LocalDefId>;
27
28#[derive(Copy, Clone)]
29pub enum UsePrelude {
30 No,
31 Yes,
32}
33
34impl From<UsePrelude> for bool {
35 fn from(up: UsePrelude) -> bool {
36 matches!(up, UsePrelude::Yes)
37 }
38}
39
40#[derive(Debug, PartialEq)]
41enum Shadowing {
42 Restricted,
43 Unrestricted,
44}
45
46impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
47 /// A generic scope visitor.
48 /// Visits scopes in order to resolve some identifier in them or perform other actions.
49 /// If the callback returns `Some` result, we stop visiting scopes and return it.
50 pub(crate) fn visit_scopes<T>(
51 &mut self,
52 scope_set: ScopeSet<'ra>,
53 parent_scope: &ParentScope<'ra>,
54 ctxt: SyntaxContext,
55 mut visitor: impl FnMut(&mut Self, Scope<'ra>, UsePrelude, SyntaxContext) -> Option<T>,
56 ) -> Option<T> {
57 // General principles:
58 // 1. Not controlled (user-defined) names should have higher priority than controlled names
59 // built into the language or standard library. This way we can add new names into the
60 // language or standard library without breaking user code.
61 // 2. "Closed set" below means new names cannot appear after the current resolution attempt.
62 // Places to search (in order of decreasing priority):
63 // (Type NS)
64 // 1. FIXME: Ribs (type parameters), there's no necessary infrastructure yet
65 // (open set, not controlled).
66 // 2. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents
67 // (open, not controlled).
68 // 3. Extern prelude (open, the open part is from macro expansions, not controlled).
69 // 4. Tool modules (closed, controlled right now, but not in the future).
70 // 5. Standard library prelude (de-facto closed, controlled).
71 // 6. Language prelude (closed, controlled).
72 // (Value NS)
73 // 1. FIXME: Ribs (local variables), there's no necessary infrastructure yet
74 // (open set, not controlled).
75 // 2. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents
76 // (open, not controlled).
77 // 3. Standard library prelude (de-facto closed, controlled).
78 // (Macro NS)
79 // 1-3. Derive helpers (open, not controlled). All ambiguities with other names
80 // are currently reported as errors. They should be higher in priority than preludes
81 // and probably even names in modules according to the "general principles" above. They
82 // also should be subject to restricted shadowing because are effectively produced by
83 // derives (you need to resolve the derive first to add helpers into scope), but they
84 // should be available before the derive is expanded for compatibility.
85 // It's mess in general, so we are being conservative for now.
86 // 1-3. `macro_rules` (open, not controlled), loop through `macro_rules` scopes. Have higher
87 // priority than prelude macros, but create ambiguities with macros in modules.
88 // 1-3. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents
89 // (open, not controlled). Have higher priority than prelude macros, but create
90 // ambiguities with `macro_rules`.
91 // 4. `macro_use` prelude (open, the open part is from macro expansions, not controlled).
92 // 4a. User-defined prelude from macro-use
93 // (open, the open part is from macro expansions, not controlled).
94 // 4b. "Standard library prelude" part implemented through `macro-use` (closed, controlled).
95 // 4c. Standard library prelude (de-facto closed, controlled).
96 // 6. Language prelude: builtin attributes (closed, controlled).
97
98 let rust_2015 = ctxt.edition().is_rust_2015();
99 let (ns, macro_kind, is_absolute_path) = match scope_set {
100 ScopeSet::All(ns) => (ns, None, false),
101 ScopeSet::AbsolutePath(ns) => (ns, None, true),
102 ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind), false),
103 ScopeSet::Late(ns, ..) => (ns, None, false),
104 };
105 let module = match scope_set {
106 // Start with the specified module.
107 ScopeSet::Late(_, module, _) => module,
108 // Jump out of trait or enum modules, they do not act as scopes.
109 _ => parent_scope.module.nearest_item_scope(),
110 };
111 let mut scope = match ns {
112 _ if is_absolute_path => Scope::CrateRoot,
113 TypeNS | ValueNS => Scope::Module(module, None),
114 MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
115 };
116 let mut ctxt = ctxt.normalize_to_macros_2_0();
117 let mut use_prelude = !module.no_implicit_prelude;
118
119 loop {
120 let visit = match scope {
121 // Derive helpers are not in scope when resolving derives in the same container.
122 Scope::DeriveHelpers(expn_id) => {
123 !(expn_id == parent_scope.expansion && macro_kind == Some(MacroKind::Derive))
124 }
125 Scope::DeriveHelpersCompat => true,
126 Scope::MacroRules(macro_rules_scope) => {
127 // Use "path compression" on `macro_rules` scope chains. This is an optimization
128 // used to avoid long scope chains, see the comments on `MacroRulesScopeRef`.
129 // As another consequence of this optimization visitors never observe invocation
130 // scopes for macros that were already expanded.
131 while let MacroRulesScope::Invocation(invoc_id) = macro_rules_scope.get() {
132 if let Some(next_scope) = self.output_macro_rules_scopes.get(&invoc_id) {
133 macro_rules_scope.set(next_scope.get());
134 } else {
135 break;
136 }
137 }
138 true
139 }
140 Scope::CrateRoot => true,
141 Scope::Module(..) => true,
142 Scope::MacroUsePrelude => use_prelude || rust_2015,
143 Scope::BuiltinAttrs => true,
144 Scope::ExternPrelude => use_prelude || is_absolute_path,
145 Scope::ToolPrelude => use_prelude,
146 Scope::StdLibPrelude => use_prelude || ns == MacroNS,
147 Scope::BuiltinTypes => true,
148 };
149
150 if visit {
151 let use_prelude = if use_prelude { UsePrelude::Yes } else { UsePrelude::No };
152 if let break_result @ Some(..) = visitor(self, scope, use_prelude, ctxt) {
153 return break_result;
154 }
155 }
156
157 scope = match scope {
158 Scope::DeriveHelpers(LocalExpnId::ROOT) => Scope::DeriveHelpersCompat,
159 Scope::DeriveHelpers(expn_id) => {
160 // Derive helpers are not visible to code generated by bang or derive macros.
161 let expn_data = expn_id.expn_data();
162 match expn_data.kind {
163 ExpnKind::Root
164 | ExpnKind::Macro(MacroKind::Bang | MacroKind::Derive, _) => {
165 Scope::DeriveHelpersCompat
166 }
167 _ => Scope::DeriveHelpers(expn_data.parent.expect_local()),
168 }
169 }
170 Scope::DeriveHelpersCompat => Scope::MacroRules(parent_scope.macro_rules),
171 Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() {
172 MacroRulesScope::Binding(binding) => {
173 Scope::MacroRules(binding.parent_macro_rules_scope)
174 }
175 MacroRulesScope::Invocation(invoc_id) => {
176 Scope::MacroRules(self.invocation_parent_scopes[&invoc_id].macro_rules)
177 }
178 MacroRulesScope::Empty => Scope::Module(module, None),
179 },
180 Scope::CrateRoot => match ns {
181 TypeNS => {
182 ctxt.adjust(ExpnId::root());
183 Scope::ExternPrelude
184 }
185 ValueNS | MacroNS => break,
186 },
187 Scope::Module(module, prev_lint_id) => {
188 use_prelude = !module.no_implicit_prelude;
189 let derive_fallback_lint_id = match scope_set {
190 ScopeSet::Late(.., lint_id) => lint_id,
191 _ => None,
192 };
193 match self.hygienic_lexical_parent(module, &mut ctxt, derive_fallback_lint_id) {
194 Some((parent_module, lint_id)) => {
195 Scope::Module(parent_module, lint_id.or(prev_lint_id))
196 }
197 None => {
198 ctxt.adjust(ExpnId::root());
199 match ns {
200 TypeNS => Scope::ExternPrelude,
201 ValueNS => Scope::StdLibPrelude,
202 MacroNS => Scope::MacroUsePrelude,
203 }
204 }
205 }
206 }
207 Scope::MacroUsePrelude => Scope::StdLibPrelude,
208 Scope::BuiltinAttrs => break, // nowhere else to search
209 Scope::ExternPrelude if is_absolute_path => break,
210 Scope::ExternPrelude => Scope::ToolPrelude,
211 Scope::ToolPrelude => Scope::StdLibPrelude,
212 Scope::StdLibPrelude => match ns {
213 TypeNS => Scope::BuiltinTypes,
214 ValueNS => break, // nowhere else to search
215 MacroNS => Scope::BuiltinAttrs,
216 },
217 Scope::BuiltinTypes => break, // nowhere else to search
218 };
219 }
220
221 None
222 }
223
224 fn hygienic_lexical_parent(
225 &mut self,
226 module: Module<'ra>,
227 ctxt: &mut SyntaxContext,
228 derive_fallback_lint_id: Option<NodeId>,
229 ) -> Option<(Module<'ra>, Option<NodeId>)> {
230 if !module.expansion.outer_expn_is_descendant_of(*ctxt) {
231 return Some((self.expn_def_scope(ctxt.remove_mark()), None));
232 }
233
234 if let ModuleKind::Block = module.kind {
235 return Some((module.parent.unwrap().nearest_item_scope(), None));
236 }
237
238 // We need to support the next case under a deprecation warning
239 // ```
240 // struct MyStruct;
241 // ---- begin: this comes from a proc macro derive
242 // mod implementation_details {
243 // // Note that `MyStruct` is not in scope here.
244 // impl SomeTrait for MyStruct { ... }
245 // }
246 // ---- end
247 // ```
248 // So we have to fall back to the module's parent during lexical resolution in this case.
249 if derive_fallback_lint_id.is_some()
250 && let Some(parent) = module.parent
251 // Inner module is inside the macro
252 && module.expansion != parent.expansion
253 // Parent module is outside of the macro
254 && module.expansion.is_descendant_of(parent.expansion)
255 // The macro is a proc macro derive
256 && let Some(def_id) = module.expansion.expn_data().macro_def_id
257 {
258 let ext = &self.get_macro_by_def_id(def_id).ext;
259 if ext.builtin_name.is_none()
260 && ext.macro_kind() == MacroKind::Derive
261 && parent.expansion.outer_expn_is_descendant_of(*ctxt)
262 {
263 return Some((parent, derive_fallback_lint_id));
264 }
265 }
266
267 None
268 }
269
270 /// This resolves the identifier `ident` in the namespace `ns` in the current lexical scope.
271 /// More specifically, we proceed up the hierarchy of scopes and return the binding for
272 /// `ident` in the first scope that defines it (or None if no scopes define it).
273 ///
274 /// A block's items are above its local variables in the scope hierarchy, regardless of where
275 /// the items are defined in the block. For example,
276 /// ```rust
277 /// fn f() {
278 /// g(); // Since there are no local variables in scope yet, this resolves to the item.
279 /// let g = || {};
280 /// fn g() {}
281 /// g(); // This resolves to the local variable `g` since it shadows the item.
282 /// }
283 /// ```
284 ///
285 /// Invariant: This must only be called during main resolution, not during
286 /// import resolution.
287 #[instrument(level = "debug", skip(self, ribs))]
288 pub(crate) fn resolve_ident_in_lexical_scope(
289 &mut self,
290 mut ident: Ident,
291 ns: Namespace,
292 parent_scope: &ParentScope<'ra>,
293 finalize: Option<Finalize>,
294 ribs: &[Rib<'ra>],
295 ignore_binding: Option<NameBinding<'ra>>,
296 ) -> Option<LexicalScopeBinding<'ra>> {
297 assert!(ns == TypeNS || ns == ValueNS);
298 let orig_ident = ident;
299 if ident.name == kw::Empty {
300 return Some(LexicalScopeBinding::Res(Res::Err));
301 }
302 let (general_span, normalized_span) = if ident.name == kw::SelfUpper {
303 // FIXME(jseyfried) improve `Self` hygiene
304 let empty_span = ident.span.with_ctxt(SyntaxContext::root());
305 (empty_span, empty_span)
306 } else if ns == TypeNS {
307 let normalized_span = ident.span.normalize_to_macros_2_0();
308 (normalized_span, normalized_span)
309 } else {
310 (ident.span.normalize_to_macro_rules(), ident.span.normalize_to_macros_2_0())
311 };
312 ident.span = general_span;
313 let normalized_ident = Ident { span: normalized_span, ..ident };
314
315 // Walk backwards up the ribs in scope.
316 let mut module = self.graph_root;
317 for (i, rib) in ribs.iter().enumerate().rev() {
318 debug!("walk rib\n{:?}", rib.bindings);
319 // Use the rib kind to determine whether we are resolving parameters
320 // (macro 2.0 hygiene) or local variables (`macro_rules` hygiene).
321 let rib_ident = if rib.kind.contains_params() { normalized_ident } else { ident };
322 if let Some((original_rib_ident_def, res)) = rib.bindings.get_key_value(&rib_ident) {
323 // The ident resolves to a type parameter or local variable.
324 return Some(LexicalScopeBinding::Res(self.validate_res_from_ribs(
325 i,
326 rib_ident,
327 *res,
328 finalize.map(|finalize| finalize.path_span),
329 *original_rib_ident_def,
330 ribs,
331 )));
332 }
333
334 module = match rib.kind {
335 RibKind::Module(module) => module,
336 RibKind::MacroDefinition(def) if def == self.macro_def(ident.span.ctxt()) => {
337 // If an invocation of this macro created `ident`, give up on `ident`
338 // and switch to `ident`'s source from the macro definition.
339 ident.span.remove_mark();
340 continue;
341 }
342 _ => continue,
343 };
344
345 match module.kind {
346 ModuleKind::Block => {} // We can see through blocks
347 _ => break,
348 }
349
350 let item = self.resolve_ident_in_module_unadjusted(
351 ModuleOrUniformRoot::Module(module),
352 ident,
353 ns,
354 parent_scope,
355 Shadowing::Unrestricted,
356 finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }),
357 ignore_binding,
358 None,
359 );
360 if let Ok(binding) = item {
361 // The ident resolves to an item.
362 return Some(LexicalScopeBinding::Item(binding));
363 }
364 }
365 self.early_resolve_ident_in_lexical_scope(
366 orig_ident,
367 ScopeSet::Late(ns, module, finalize.map(|finalize| finalize.node_id)),
368 parent_scope,
369 finalize,
370 finalize.is_some(),
371 ignore_binding,
372 None,
373 )
374 .ok()
375 .map(LexicalScopeBinding::Item)
376 }
377
378 /// Resolve an identifier in lexical scope.
379 /// This is a variation of `fn resolve_ident_in_lexical_scope` that can be run during
380 /// expansion and import resolution (perhaps they can be merged in the future).
381 /// The function is used for resolving initial segments of macro paths (e.g., `foo` in
382 /// `foo::bar!();` or `foo!();`) and also for import paths on 2018 edition.
383 #[instrument(level = "debug", skip(self))]
384 pub(crate) fn early_resolve_ident_in_lexical_scope(
385 &mut self,
386 orig_ident: Ident,
387 scope_set: ScopeSet<'ra>,
388 parent_scope: &ParentScope<'ra>,
389 finalize: Option<Finalize>,
390 force: bool,
391 ignore_binding: Option<NameBinding<'ra>>,
392 ignore_import: Option<Import<'ra>>,
393 ) -> Result<NameBinding<'ra>, Determinacy> {
394 bitflags::bitflags! {
395 #[derive(Clone, Copy)]
396 struct Flags: u8 {
397 const MACRO_RULES = 1 << 0;
398 const MODULE = 1 << 1;
399 const MISC_SUGGEST_CRATE = 1 << 2;
400 const MISC_SUGGEST_SELF = 1 << 3;
401 const MISC_FROM_PRELUDE = 1 << 4;
402 }
403 }
404
405 assert!(force || finalize.is_none()); // `finalize` implies `force`
406
407 // Make sure `self`, `super` etc produce an error when passed to here.
408 if orig_ident.is_path_segment_keyword() {
409 return Err(Determinacy::Determined);
410 }
411
412 let (ns, macro_kind) = match scope_set {
413 ScopeSet::All(ns) => (ns, None),
414 ScopeSet::AbsolutePath(ns) => (ns, None),
415 ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
416 ScopeSet::Late(ns, ..) => (ns, None),
417 };
418
419 // This is *the* result, resolution from the scope closest to the resolved identifier.
420 // However, sometimes this result is "weak" because it comes from a glob import or
421 // a macro expansion, and in this case it cannot shadow names from outer scopes, e.g.
422 // mod m { ... } // solution in outer scope
423 // {
424 // use prefix::*; // imports another `m` - innermost solution
425 // // weak, cannot shadow the outer `m`, need to report ambiguity error
426 // m::mac!();
427 // }
428 // So we have to save the innermost solution and continue searching in outer scopes
429 // to detect potential ambiguities.
430 let mut innermost_result: Option<(NameBinding<'_>, Flags)> = None;
431 let mut determinacy = Determinacy::Determined;
432
433 // Go through all the scopes and try to resolve the name.
434 let break_result = self.visit_scopes(
435 scope_set,
436 parent_scope,
437 orig_ident.span.ctxt(),
438 |this, scope, use_prelude, ctxt| {
439 let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt));
440 let result = match scope {
441 Scope::DeriveHelpers(expn_id) => {
442 if let Some(binding) = this.helper_attrs.get(&expn_id).and_then(|attrs| {
443 attrs.iter().rfind(|(i, _)| ident == *i).map(|(_, binding)| *binding)
444 }) {
445 Ok((binding, Flags::empty()))
446 } else {
447 Err(Determinacy::Determined)
448 }
449 }
450 Scope::DeriveHelpersCompat => {
451 // FIXME: Try running this logic earlier, to allocate name bindings for
452 // legacy derive helpers when creating an attribute invocation with
453 // following derives. Legacy derive helpers are not common, so it shouldn't
454 // affect performance. It should also allow to remove the `derives`
455 // component from `ParentScope`.
456 let mut result = Err(Determinacy::Determined);
457 for derive in parent_scope.derives {
458 let parent_scope = &ParentScope { derives: &[], ..*parent_scope };
459 match this.resolve_macro_path(
460 derive,
461 Some(MacroKind::Derive),
462 parent_scope,
463 true,
464 force,
465 ignore_import,
466 ) {
467 Ok((Some(ext), _)) => {
468 if ext.helper_attrs.contains(&ident.name) {
469 let binding = (
470 Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat),
471 Visibility::Public,
472 derive.span,
473 LocalExpnId::ROOT,
474 )
475 .to_name_binding(this.arenas);
476 result = Ok((binding, Flags::empty()));
477 break;
478 }
479 }
480 Ok(_) | Err(Determinacy::Determined) => {}
481 Err(Determinacy::Undetermined) => {
482 result = Err(Determinacy::Undetermined)
483 }
484 }
485 }
486 result
487 }
488 Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() {
489 MacroRulesScope::Binding(macro_rules_binding)
490 if ident == macro_rules_binding.ident =>
491 {
492 Ok((macro_rules_binding.binding, Flags::MACRO_RULES))
493 }
494 MacroRulesScope::Invocation(_) => Err(Determinacy::Undetermined),
495 _ => Err(Determinacy::Determined),
496 },
497 Scope::CrateRoot => {
498 let root_ident = Ident::new(kw::PathRoot, ident.span);
499 let root_module = this.resolve_crate_root(root_ident);
500 let binding = this.resolve_ident_in_module(
501 ModuleOrUniformRoot::Module(root_module),
502 ident,
503 ns,
504 parent_scope,
505 finalize,
506 ignore_binding,
507 ignore_import,
508 );
509 match binding {
510 Ok(binding) => Ok((binding, Flags::MODULE | Flags::MISC_SUGGEST_CRATE)),
511 Err((Determinacy::Undetermined, Weak::No)) => {
512 return Some(Err(Determinacy::determined(force)));
513 }
514 Err((Determinacy::Undetermined, Weak::Yes)) => {
515 Err(Determinacy::Undetermined)
516 }
517 Err((Determinacy::Determined, _)) => Err(Determinacy::Determined),
518 }
519 }
520 Scope::Module(module, derive_fallback_lint_id) => {
521 let adjusted_parent_scope = &ParentScope { module, ..*parent_scope };
522 let binding = this.resolve_ident_in_module_unadjusted(
523 ModuleOrUniformRoot::Module(module),
524 ident,
525 ns,
526 adjusted_parent_scope,
527 if matches!(scope_set, ScopeSet::Late(..)) {
528 Shadowing::Unrestricted
529 } else {
530 Shadowing::Restricted
531 },
532 finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }),
533 ignore_binding,
534 ignore_import,
535 );
536 match binding {
537 Ok(binding) => {
538 if let Some(lint_id) = derive_fallback_lint_id {
539 this.lint_buffer.buffer_lint(
540 PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
541 lint_id,
542 orig_ident.span,
543 BuiltinLintDiag::ProcMacroDeriveResolutionFallback {
544 span: orig_ident.span,
545 ns,
546 ident,
547 },
548 );
549 }
550 let misc_flags = if module == this.graph_root {
551 Flags::MISC_SUGGEST_CRATE
552 } else if module.is_normal() {
553 Flags::MISC_SUGGEST_SELF
554 } else {
555 Flags::empty()
556 };
557 Ok((binding, Flags::MODULE | misc_flags))
558 }
559 Err((Determinacy::Undetermined, Weak::No)) => {
560 return Some(Err(Determinacy::determined(force)));
561 }
562 Err((Determinacy::Undetermined, Weak::Yes)) => {
563 Err(Determinacy::Undetermined)
564 }
565 Err((Determinacy::Determined, _)) => Err(Determinacy::Determined),
566 }
567 }
568 Scope::MacroUsePrelude => {
569 match this.macro_use_prelude.get(&ident.name).cloned() {
570 Some(binding) => Ok((binding, Flags::MISC_FROM_PRELUDE)),
571 None => Err(Determinacy::determined(
572 this.graph_root.unexpanded_invocations.borrow().is_empty(),
573 )),
574 }
575 }
576 Scope::BuiltinAttrs => match this.builtin_attrs_bindings.get(&ident.name) {
577 Some(binding) => Ok((*binding, Flags::empty())),
578 None => Err(Determinacy::Determined),
579 },
580 Scope::ExternPrelude => {
581 match this.extern_prelude_get(ident, finalize.is_some()) {
582 Some(binding) => Ok((binding, Flags::empty())),
583 None => Err(Determinacy::determined(
584 this.graph_root.unexpanded_invocations.borrow().is_empty(),
585 )),
586 }
587 }
588 Scope::ToolPrelude => match this.registered_tool_bindings.get(&ident) {
589 Some(binding) => Ok((*binding, Flags::empty())),
590 None => Err(Determinacy::Determined),
591 },
592 Scope::StdLibPrelude => {
593 let mut result = Err(Determinacy::Determined);
594 if let Some(prelude) = this.prelude
595 && let Ok(binding) = this.resolve_ident_in_module_unadjusted(
596 ModuleOrUniformRoot::Module(prelude),
597 ident,
598 ns,
599 parent_scope,
600 Shadowing::Unrestricted,
601 None,
602 ignore_binding,
603 ignore_import,
604 )
605 && (matches!(use_prelude, UsePrelude::Yes)
606 || this.is_builtin_macro(binding.res()))
607 {
608 result = Ok((binding, Flags::MISC_FROM_PRELUDE));
609 }
610
611 result
612 }
613 Scope::BuiltinTypes => match this.builtin_types_bindings.get(&ident.name) {
614 Some(binding) => {
615 if matches!(ident.name, sym::f16)
616 && !this.tcx.features().f16()
617 && !ident.span.allows_unstable(sym::f16)
618 && finalize.is_some()
619 && innermost_result.is_none()
620 {
621 feature_err(
622 this.tcx.sess,
623 sym::f16,
624 ident.span,
625 "the type `f16` is unstable",
626 )
627 .emit();
628 }
629 if matches!(ident.name, sym::f128)
630 && !this.tcx.features().f128()
631 && !ident.span.allows_unstable(sym::f128)
632 && finalize.is_some()
633 && innermost_result.is_none()
634 {
635 feature_err(
636 this.tcx.sess,
637 sym::f128,
638 ident.span,
639 "the type `f128` is unstable",
640 )
641 .emit();
642 }
643 Ok((*binding, Flags::empty()))
644 }
645 None => Err(Determinacy::Determined),
646 },
647 };
648
649 match result {
650 Ok((binding, flags))
651 if sub_namespace_match(binding.macro_kind(), macro_kind) =>
652 {
653 if finalize.is_none() || matches!(scope_set, ScopeSet::Late(..)) {
654 return Some(Ok(binding));
655 }
656
657 if let Some((innermost_binding, innermost_flags)) = innermost_result {
658 // Found another solution, if the first one was "weak", report an error.
659 let (res, innermost_res) = (binding.res(), innermost_binding.res());
660 if res != innermost_res {
661 let is_builtin = |res| {
662 matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Builtin(..)))
663 };
664 let derive_helper =
665 Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
666 let derive_helper_compat =
667 Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat);
668
669 let ambiguity_error_kind = if is_builtin(innermost_res)
670 || is_builtin(res)
671 {
672 Some(AmbiguityKind::BuiltinAttr)
673 } else if innermost_res == derive_helper_compat
674 || res == derive_helper_compat && innermost_res != derive_helper
675 {
676 Some(AmbiguityKind::DeriveHelper)
677 } else if innermost_flags.contains(Flags::MACRO_RULES)
678 && flags.contains(Flags::MODULE)
679 && !this.disambiguate_macro_rules_vs_modularized(
680 innermost_binding,
681 binding,
682 )
683 || flags.contains(Flags::MACRO_RULES)
684 && innermost_flags.contains(Flags::MODULE)
685 && !this.disambiguate_macro_rules_vs_modularized(
686 binding,
687 innermost_binding,
688 )
689 {
690 Some(AmbiguityKind::MacroRulesVsModularized)
691 } else if innermost_binding.is_glob_import() {
692 Some(AmbiguityKind::GlobVsOuter)
693 } else if innermost_binding
694 .may_appear_after(parent_scope.expansion, binding)
695 {
696 Some(AmbiguityKind::MoreExpandedVsOuter)
697 } else {
698 None
699 };
700 if let Some(kind) = ambiguity_error_kind {
701 let misc = |f: Flags| {
702 if f.contains(Flags::MISC_SUGGEST_CRATE) {
703 AmbiguityErrorMisc::SuggestCrate
704 } else if f.contains(Flags::MISC_SUGGEST_SELF) {
705 AmbiguityErrorMisc::SuggestSelf
706 } else if f.contains(Flags::MISC_FROM_PRELUDE) {
707 AmbiguityErrorMisc::FromPrelude
708 } else {
709 AmbiguityErrorMisc::None
710 }
711 };
712 this.ambiguity_errors.push(AmbiguityError {
713 kind,
714 ident: orig_ident,
715 b1: innermost_binding,
716 b2: binding,
717 warning: false,
718 misc1: misc(innermost_flags),
719 misc2: misc(flags),
720 });
721 return Some(Ok(innermost_binding));
722 }
723 }
724 } else {
725 // Found the first solution.
726 innermost_result = Some((binding, flags));
727 }
728 }
729 Ok(..) | Err(Determinacy::Determined) => {}
730 Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined,
731 }
732
733 None
734 },
735 );
736
737 if let Some(break_result) = break_result {
738 return break_result;
739 }
740
741 // The first found solution was the only one, return it.
742 if let Some((binding, _)) = innermost_result {
743 return Ok(binding);
744 }
745
746 Err(Determinacy::determined(determinacy == Determinacy::Determined || force))
747 }
748
749 #[instrument(level = "debug", skip(self))]
750 pub(crate) fn maybe_resolve_ident_in_module(
751 &mut self,
752 module: ModuleOrUniformRoot<'ra>,
753 ident: Ident,
754 ns: Namespace,
755 parent_scope: &ParentScope<'ra>,
756 ignore_import: Option<Import<'ra>>,
757 ) -> Result<NameBinding<'ra>, Determinacy> {
758 self.resolve_ident_in_module(module, ident, ns, parent_scope, None, None, ignore_import)
759 .map_err(|(determinacy, _)| determinacy)
760 }
761
762 #[instrument(level = "debug", skip(self))]
763 pub(crate) fn resolve_ident_in_module(
764 &mut self,
765 module: ModuleOrUniformRoot<'ra>,
766 mut ident: Ident,
767 ns: Namespace,
768 parent_scope: &ParentScope<'ra>,
769 finalize: Option<Finalize>,
770 ignore_binding: Option<NameBinding<'ra>>,
771 ignore_import: Option<Import<'ra>>,
772 ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
773 let tmp_parent_scope;
774 let mut adjusted_parent_scope = parent_scope;
775 match module {
776 ModuleOrUniformRoot::Module(m) => {
777 if let Some(def) = ident.span.normalize_to_macros_2_0_and_adjust(m.expansion) {
778 tmp_parent_scope =
779 ParentScope { module: self.expn_def_scope(def), ..*parent_scope };
780 adjusted_parent_scope = &tmp_parent_scope;
781 }
782 }
783 ModuleOrUniformRoot::ExternPrelude => {
784 ident.span.normalize_to_macros_2_0_and_adjust(ExpnId::root());
785 }
786 ModuleOrUniformRoot::CrateRootAndExternPrelude | ModuleOrUniformRoot::CurrentScope => {
787 // No adjustments
788 }
789 }
790 self.resolve_ident_in_module_unadjusted(
791 module,
792 ident,
793 ns,
794 adjusted_parent_scope,
795 Shadowing::Unrestricted,
796 finalize,
797 ignore_binding,
798 ignore_import,
799 )
800 }
801
802 /// Attempts to resolve `ident` in namespaces `ns` of `module`.
803 /// Invariant: if `finalize` is `Some`, expansion and import resolution must be complete.
804 #[instrument(level = "debug", skip(self))]
805 fn resolve_ident_in_module_unadjusted(
806 &mut self,
807 module: ModuleOrUniformRoot<'ra>,
808 ident: Ident,
809 ns: Namespace,
810 parent_scope: &ParentScope<'ra>,
811 shadowing: Shadowing,
812 finalize: Option<Finalize>,
813 // This binding should be ignored during in-module resolution, so that we don't get
814 // "self-confirming" import resolutions during import validation and checking.
815 ignore_binding: Option<NameBinding<'ra>>,
816 ignore_import: Option<Import<'ra>>,
817 ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
818 let module = match module {
819 ModuleOrUniformRoot::Module(module) => module,
820 ModuleOrUniformRoot::CrateRootAndExternPrelude => {
821 assert_eq!(shadowing, Shadowing::Unrestricted);
822 let binding = self.early_resolve_ident_in_lexical_scope(
823 ident,
824 ScopeSet::AbsolutePath(ns),
825 parent_scope,
826 finalize,
827 finalize.is_some(),
828 ignore_binding,
829 ignore_import,
830 );
831 return binding.map_err(|determinacy| (determinacy, Weak::No));
832 }
833 ModuleOrUniformRoot::ExternPrelude => {
834 assert_eq!(shadowing, Shadowing::Unrestricted);
835 return if ns != TypeNS {
836 Err((Determined, Weak::No))
837 } else if let Some(binding) = self.extern_prelude_get(ident, finalize.is_some()) {
838 Ok(binding)
839 } else if !self.graph_root.unexpanded_invocations.borrow().is_empty() {
840 // Macro-expanded `extern crate` items can add names to extern prelude.
841 Err((Undetermined, Weak::No))
842 } else {
843 Err((Determined, Weak::No))
844 };
845 }
846 ModuleOrUniformRoot::CurrentScope => {
847 assert_eq!(shadowing, Shadowing::Unrestricted);
848 if ns == TypeNS {
849 if ident.name == kw::Crate || ident.name == kw::DollarCrate {
850 let module = self.resolve_crate_root(ident);
851 return Ok(self.module_self_bindings[&module]);
852 } else if ident.name == kw::Super || ident.name == kw::SelfLower {
853 // FIXME: Implement these with renaming requirements so that e.g.
854 // `use super;` doesn't work, but `use super as name;` does.
855 // Fall through here to get an error from `early_resolve_...`.
856 }
857 }
858
859 let binding = self.early_resolve_ident_in_lexical_scope(
860 ident,
861 ScopeSet::All(ns),
862 parent_scope,
863 finalize,
864 finalize.is_some(),
865 ignore_binding,
866 ignore_import,
867 );
868 return binding.map_err(|determinacy| (determinacy, Weak::No));
869 }
870 };
871
872 let key = BindingKey::new(ident, ns);
873 let resolution =
874 self.resolution(module, key).try_borrow_mut().map_err(|_| (Determined, Weak::No))?; // This happens when there is a cycle of imports.
875
876 // If the primary binding is unusable, search further and return the shadowed glob
877 // binding if it exists. What we really want here is having two separate scopes in
878 // a module - one for non-globs and one for globs, but until that's done use this
879 // hack to avoid inconsistent resolution ICEs during import validation.
880 let binding = [resolution.binding, resolution.shadowed_glob]
881 .into_iter()
882 .find_map(|binding| if binding == ignore_binding { None } else { binding });
883
884 if let Some(Finalize { path_span, report_private, used, root_span, .. }) = finalize {
885 let Some(binding) = binding else {
886 return Err((Determined, Weak::No));
887 };
888
889 if !self.is_accessible_from(binding.vis, parent_scope.module) {
890 if report_private {
891 self.privacy_errors.push(PrivacyError {
892 ident,
893 binding,
894 dedup_span: path_span,
895 outermost_res: None,
896 parent_scope: *parent_scope,
897 single_nested: path_span != root_span,
898 });
899 } else {
900 return Err((Determined, Weak::No));
901 }
902 }
903
904 // Forbid expanded shadowing to avoid time travel.
905 if let Some(shadowed_glob) = resolution.shadowed_glob
906 && shadowing == Shadowing::Restricted
907 && binding.expansion != LocalExpnId::ROOT
908 && binding.res() != shadowed_glob.res()
909 {
910 self.ambiguity_errors.push(AmbiguityError {
911 kind: AmbiguityKind::GlobVsExpanded,
912 ident,
913 b1: binding,
914 b2: shadowed_glob,
915 warning: false,
916 misc1: AmbiguityErrorMisc::None,
917 misc2: AmbiguityErrorMisc::None,
918 });
919 }
920
921 if shadowing == Shadowing::Unrestricted
922 && binding.expansion != LocalExpnId::ROOT
923 && let NameBindingKind::Import { import, .. } = binding.kind
924 && matches!(import.kind, ImportKind::MacroExport)
925 {
926 self.macro_expanded_macro_export_errors.insert((path_span, binding.span));
927 }
928
929 self.record_use(ident, binding, used);
930 return Ok(binding);
931 }
932
933 let check_usable = |this: &mut Self, binding: NameBinding<'ra>| {
934 let usable = this.is_accessible_from(binding.vis, parent_scope.module);
935 if usable { Ok(binding) } else { Err((Determined, Weak::No)) }
936 };
937
938 // Items and single imports are not shadowable, if we have one, then it's determined.
939 if let Some(binding) = binding
940 && !binding.is_glob_import()
941 {
942 return check_usable(self, binding);
943 }
944
945 // --- From now on we either have a glob resolution or no resolution. ---
946
947 // Check if one of single imports can still define the name,
948 // if it can then our result is not determined and can be invalidated.
949 for single_import in &resolution.single_imports {
950 if ignore_import == Some(*single_import) {
951 // This branch handles a cycle in single imports.
952 //
953 // For example:
954 // ```
955 // use a::b;
956 // use b as a;
957 // ```
958 // 1. Record `use a::b` as the `ignore_import` and attempt to locate `a` in the
959 // current module.
960 // 2. Encounter the import `use b as a`, which is a `single_import` for `a`,
961 // and try to find `b` in the current module.
962 // 3. Re-encounter the `use a::b` import since it's a `single_import` of `b`.
963 // This leads to entering this branch.
964 continue;
965 }
966 if !self.is_accessible_from(single_import.vis, parent_scope.module) {
967 continue;
968 }
969 if let Some(ignored) = ignore_binding
970 && let NameBindingKind::Import { import, .. } = ignored.kind
971 && import == *single_import
972 {
973 // Ignore not just the binding itself, but if it has a shadowed_glob,
974 // ignore that, too, because this loop is supposed to only process
975 // named imports.
976 continue;
977 }
978
979 let Some(module) = single_import.imported_module.get() else {
980 return Err((Undetermined, Weak::No));
981 };
982 let ImportKind::Single { source, target, target_bindings, .. } = &single_import.kind
983 else {
984 unreachable!();
985 };
986 if source != target {
987 // This branch allows the binding to be defined or updated later if the target name
988 // can hide the source.
989 if target_bindings.iter().all(|binding| binding.get().is_none()) {
990 // None of the target bindings are available, so we can't determine
991 // if this binding is correct or not.
992 // See more details in #124840
993 return Err((Undetermined, Weak::No));
994 } else if target_bindings[ns].get().is_none() && binding.is_some() {
995 // `binding.is_some()` avoids the condition where the binding
996 // truly doesn't exist in this namespace and should return `Err(Determined)`.
997 return Err((Undetermined, Weak::No));
998 }
999 }
1000
1001 match self.resolve_ident_in_module(
1002 module,
1003 *source,
1004 ns,
1005 &single_import.parent_scope,
1006 None,
1007 ignore_binding,
1008 ignore_import,
1009 ) {
1010 Err((Determined, _)) => continue,
1011 Ok(binding)
1012 if !self.is_accessible_from(binding.vis, single_import.parent_scope.module) =>
1013 {
1014 continue;
1015 }
1016 Ok(_) | Err((Undetermined, _)) => return Err((Undetermined, Weak::No)),
1017 }
1018 }
1019
1020 // So we have a resolution that's from a glob import. This resolution is determined
1021 // if it cannot be shadowed by some new item/import expanded from a macro.
1022 // This happens either if there are no unexpanded macros, or expanded names cannot
1023 // shadow globs (that happens in macro namespace or with restricted shadowing).
1024 //
1025 // Additionally, any macro in any module can plant names in the root module if it creates
1026 // `macro_export` macros, so the root module effectively has unresolved invocations if any
1027 // module has unresolved invocations.
1028 // However, it causes resolution/expansion to stuck too often (#53144), so, to make
1029 // progress, we have to ignore those potential unresolved invocations from other modules
1030 // and prohibit access to macro-expanded `macro_export` macros instead (unless restricted
1031 // shadowing is enabled, see `macro_expanded_macro_export_errors`).
1032 if let Some(binding) = binding {
1033 if binding.determined() || ns == MacroNS || shadowing == Shadowing::Restricted {
1034 return check_usable(self, binding);
1035 } else {
1036 return Err((Undetermined, Weak::No));
1037 }
1038 }
1039
1040 // --- From now on we have no resolution. ---
1041
1042 // Now we are in situation when new item/import can appear only from a glob or a macro
1043 // expansion. With restricted shadowing names from globs and macro expansions cannot
1044 // shadow names from outer scopes, so we can freely fallback from module search to search
1045 // in outer scopes. For `early_resolve_ident_in_lexical_scope` to continue search in outer
1046 // scopes we return `Undetermined` with `Weak::Yes`.
1047
1048 // Check if one of unexpanded macros can still define the name,
1049 // if it can then our "no resolution" result is not determined and can be invalidated.
1050 if !module.unexpanded_invocations.borrow().is_empty() {
1051 return Err((Undetermined, Weak::Yes));
1052 }
1053
1054 // Check if one of glob imports can still define the name,
1055 // if it can then our "no resolution" result is not determined and can be invalidated.
1056 for glob_import in module.globs.borrow().iter() {
1057 if ignore_import == Some(*glob_import) {
1058 continue;
1059 }
1060 if !self.is_accessible_from(glob_import.vis, parent_scope.module) {
1061 continue;
1062 }
1063 let module = match glob_import.imported_module.get() {
1064 Some(ModuleOrUniformRoot::Module(module)) => module,
1065 Some(_) => continue,
1066 None => return Err((Undetermined, Weak::Yes)),
1067 };
1068 let tmp_parent_scope;
1069 let (mut adjusted_parent_scope, mut ident) =
1070 (parent_scope, ident.normalize_to_macros_2_0());
1071 match ident.span.glob_adjust(module.expansion, glob_import.span) {
1072 Some(Some(def)) => {
1073 tmp_parent_scope =
1074 ParentScope { module: self.expn_def_scope(def), ..*parent_scope };
1075 adjusted_parent_scope = &tmp_parent_scope;
1076 }
1077 Some(None) => {}
1078 None => continue,
1079 };
1080 let result = self.resolve_ident_in_module_unadjusted(
1081 ModuleOrUniformRoot::Module(module),
1082 ident,
1083 ns,
1084 adjusted_parent_scope,
1085 Shadowing::Unrestricted,
1086 None,
1087 ignore_binding,
1088 ignore_import,
1089 );
1090
1091 match result {
1092 Err((Determined, _)) => continue,
1093 Ok(binding)
1094 if !self.is_accessible_from(binding.vis, glob_import.parent_scope.module) =>
1095 {
1096 continue;
1097 }
1098 Ok(_) | Err((Undetermined, _)) => return Err((Undetermined, Weak::Yes)),
1099 }
1100 }
1101
1102 // No resolution and no one else can define the name - determinate error.
1103 Err((Determined, Weak::No))
1104 }
1105
1106 /// Validate a local resolution (from ribs).
1107 #[instrument(level = "debug", skip(self, all_ribs))]
1108 fn validate_res_from_ribs(
1109 &mut self,
1110 rib_index: usize,
1111 rib_ident: Ident,
1112 mut res: Res,
1113 finalize: Option<Span>,
1114 original_rib_ident_def: Ident,
1115 all_ribs: &[Rib<'ra>],
1116 ) -> Res {
1117 debug!("validate_res_from_ribs({:?})", res);
1118 let ribs = &all_ribs[rib_index + 1..];
1119
1120 // An invalid forward use of a generic parameter from a previous default.
1121 if let RibKind::ForwardGenericParamBan = all_ribs[rib_index].kind {
1122 if let Some(span) = finalize {
1123 let res_error = if rib_ident.name == kw::SelfUpper {
1124 ResolutionError::SelfInGenericParamDefault
1125 } else {
1126 ResolutionError::ForwardDeclaredGenericParam
1127 };
1128 self.report_error(span, res_error);
1129 }
1130 assert_eq!(res, Res::Err);
1131 return Res::Err;
1132 }
1133
1134 match res {
1135 Res::Local(_) => {
1136 use ResolutionError::*;
1137 let mut res_err = None;
1138
1139 for rib in ribs {
1140 match rib.kind {
1141 RibKind::Normal
1142 | RibKind::FnOrCoroutine
1143 | RibKind::Module(..)
1144 | RibKind::MacroDefinition(..)
1145 | RibKind::ForwardGenericParamBan => {
1146 // Nothing to do. Continue.
1147 }
1148 RibKind::Item(..) | RibKind::AssocItem => {
1149 // This was an attempt to access an upvar inside a
1150 // named function item. This is not allowed, so we
1151 // report an error.
1152 if let Some(span) = finalize {
1153 // We don't immediately trigger a resolve error, because
1154 // we want certain other resolution errors (namely those
1155 // emitted for `ConstantItemRibKind` below) to take
1156 // precedence.
1157 res_err = Some((span, CannotCaptureDynamicEnvironmentInFnItem));
1158 }
1159 }
1160 RibKind::ConstantItem(_, item) => {
1161 // Still doesn't deal with upvars
1162 if let Some(span) = finalize {
1163 let (span, resolution_error) = match item {
1164 None if rib_ident.name == kw::SelfLower => {
1165 (span, LowercaseSelf)
1166 }
1167 None => {
1168 // If we have a `let name = expr;`, we have the span for
1169 // `name` and use that to see if it is followed by a type
1170 // specifier. If not, then we know we need to suggest
1171 // `const name: Ty = expr;`. This is a heuristic, it will
1172 // break down in the presence of macros.
1173 let sm = self.tcx.sess.source_map();
1174 let type_span = match sm.span_look_ahead(
1175 original_rib_ident_def.span,
1176 ":",
1177 None,
1178 ) {
1179 None => {
1180 Some(original_rib_ident_def.span.shrink_to_hi())
1181 }
1182 Some(_) => None,
1183 };
1184 (
1185 rib_ident.span,
1186 AttemptToUseNonConstantValueInConstant {
1187 ident: original_rib_ident_def,
1188 suggestion: "const",
1189 current: "let",
1190 type_span,
1191 },
1192 )
1193 }
1194 Some((ident, kind)) => (
1195 span,
1196 AttemptToUseNonConstantValueInConstant {
1197 ident,
1198 suggestion: "let",
1199 current: kind.as_str(),
1200 type_span: None,
1201 },
1202 ),
1203 };
1204 self.report_error(span, resolution_error);
1205 }
1206 return Res::Err;
1207 }
1208 RibKind::ConstParamTy => {
1209 if let Some(span) = finalize {
1210 self.report_error(
1211 span,
1212 ParamInTyOfConstParam {
1213 name: rib_ident.name,
1214 param_kind: None,
1215 },
1216 );
1217 }
1218 return Res::Err;
1219 }
1220 RibKind::InlineAsmSym => {
1221 if let Some(span) = finalize {
1222 self.report_error(span, InvalidAsmSym);
1223 }
1224 return Res::Err;
1225 }
1226 }
1227 }
1228 if let Some((span, res_err)) = res_err {
1229 self.report_error(span, res_err);
1230 return Res::Err;
1231 }
1232 }
1233 Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {
1234 for rib in ribs {
1235 let (has_generic_params, def_kind) = match rib.kind {
1236 RibKind::Normal
1237 | RibKind::FnOrCoroutine
1238 | RibKind::Module(..)
1239 | RibKind::MacroDefinition(..)
1240 | RibKind::InlineAsmSym
1241 | RibKind::AssocItem
1242 | RibKind::ForwardGenericParamBan => {
1243 // Nothing to do. Continue.
1244 continue;
1245 }
1246
1247 RibKind::ConstantItem(trivial, _) => {
1248 if let ConstantHasGenerics::No(cause) = trivial {
1249 // HACK(min_const_generics): If we encounter `Self` in an anonymous
1250 // constant we can't easily tell if it's generic at this stage, so
1251 // we instead remember this and then enforce the self type to be
1252 // concrete later on.
1253 if let Res::SelfTyAlias {
1254 alias_to: def,
1255 forbid_generic: _,
1256 is_trait_impl,
1257 } = res
1258 {
1259 res = Res::SelfTyAlias {
1260 alias_to: def,
1261 forbid_generic: true,
1262 is_trait_impl,
1263 }
1264 } else {
1265 if let Some(span) = finalize {
1266 let error = match cause {
1267 NoConstantGenericsReason::IsEnumDiscriminant => {
1268 ResolutionError::ParamInEnumDiscriminant {
1269 name: rib_ident.name,
1270 param_kind: ParamKindInEnumDiscriminant::Type,
1271 }
1272 }
1273 NoConstantGenericsReason::NonTrivialConstArg => {
1274 ResolutionError::ParamInNonTrivialAnonConst {
1275 name: rib_ident.name,
1276 param_kind:
1277 ParamKindInNonTrivialAnonConst::Type,
1278 }
1279 }
1280 };
1281 let _: ErrorGuaranteed = self.report_error(span, error);
1282 }
1283
1284 return Res::Err;
1285 }
1286 }
1287
1288 continue;
1289 }
1290
1291 // This was an attempt to use a type parameter outside its scope.
1292 RibKind::Item(has_generic_params, def_kind) => {
1293 (has_generic_params, def_kind)
1294 }
1295 RibKind::ConstParamTy => {
1296 if let Some(span) = finalize {
1297 self.report_error(
1298 span,
1299 ResolutionError::ParamInTyOfConstParam {
1300 name: rib_ident.name,
1301 param_kind: Some(errors::ParamKindInTyOfConstParam::Type),
1302 },
1303 );
1304 }
1305 return Res::Err;
1306 }
1307 };
1308
1309 if let Some(span) = finalize {
1310 self.report_error(
1311 span,
1312 ResolutionError::GenericParamsFromOuterItem(
1313 res,
1314 has_generic_params,
1315 def_kind,
1316 ),
1317 );
1318 }
1319 return Res::Err;
1320 }
1321 }
1322 Res::Def(DefKind::ConstParam, _) => {
1323 for rib in ribs {
1324 let (has_generic_params, def_kind) = match rib.kind {
1325 RibKind::Normal
1326 | RibKind::FnOrCoroutine
1327 | RibKind::Module(..)
1328 | RibKind::MacroDefinition(..)
1329 | RibKind::InlineAsmSym
1330 | RibKind::AssocItem
1331 | RibKind::ForwardGenericParamBan => continue,
1332
1333 RibKind::ConstantItem(trivial, _) => {
1334 if let ConstantHasGenerics::No(cause) = trivial {
1335 if let Some(span) = finalize {
1336 let error = match cause {
1337 NoConstantGenericsReason::IsEnumDiscriminant => {
1338 ResolutionError::ParamInEnumDiscriminant {
1339 name: rib_ident.name,
1340 param_kind: ParamKindInEnumDiscriminant::Const,
1341 }
1342 }
1343 NoConstantGenericsReason::NonTrivialConstArg => {
1344 ResolutionError::ParamInNonTrivialAnonConst {
1345 name: rib_ident.name,
1346 param_kind: ParamKindInNonTrivialAnonConst::Const {
1347 name: rib_ident.name,
1348 },
1349 }
1350 }
1351 };
1352 self.report_error(span, error);
1353 }
1354
1355 return Res::Err;
1356 }
1357
1358 continue;
1359 }
1360
1361 RibKind::Item(has_generic_params, def_kind) => {
1362 (has_generic_params, def_kind)
1363 }
1364 RibKind::ConstParamTy => {
1365 if let Some(span) = finalize {
1366 self.report_error(
1367 span,
1368 ResolutionError::ParamInTyOfConstParam {
1369 name: rib_ident.name,
1370 param_kind: Some(errors::ParamKindInTyOfConstParam::Const),
1371 },
1372 );
1373 }
1374 return Res::Err;
1375 }
1376 };
1377
1378 // This was an attempt to use a const parameter outside its scope.
1379 if let Some(span) = finalize {
1380 self.report_error(
1381 span,
1382 ResolutionError::GenericParamsFromOuterItem(
1383 res,
1384 has_generic_params,
1385 def_kind,
1386 ),
1387 );
1388 }
1389 return Res::Err;
1390 }
1391 }
1392 _ => {}
1393 }
1394 res
1395 }
1396
1397 #[instrument(level = "debug", skip(self))]
1398 pub(crate) fn maybe_resolve_path(
1399 &mut self,
1400 path: &[Segment],
1401 opt_ns: Option<Namespace>, // `None` indicates a module path in import
1402 parent_scope: &ParentScope<'ra>,
1403 ignore_import: Option<Import<'ra>>,
1404 ) -> PathResult<'ra> {
1405 self.resolve_path_with_ribs(path, opt_ns, parent_scope, None, None, None, ignore_import)
1406 }
1407
1408 #[instrument(level = "debug", skip(self))]
1409 pub(crate) fn resolve_path(
1410 &mut self,
1411 path: &[Segment],
1412 opt_ns: Option<Namespace>, // `None` indicates a module path in import
1413 parent_scope: &ParentScope<'ra>,
1414 finalize: Option<Finalize>,
1415 ignore_binding: Option<NameBinding<'ra>>,
1416 ignore_import: Option<Import<'ra>>,
1417 ) -> PathResult<'ra> {
1418 self.resolve_path_with_ribs(
1419 path,
1420 opt_ns,
1421 parent_scope,
1422 finalize,
1423 None,
1424 ignore_binding,
1425 ignore_import,
1426 )
1427 }
1428
1429 pub(crate) fn resolve_path_with_ribs(
1430 &mut self,
1431 path: &[Segment],
1432 opt_ns: Option<Namespace>, // `None` indicates a module path in import
1433 parent_scope: &ParentScope<'ra>,
1434 finalize: Option<Finalize>,
1435 ribs: Option<&PerNS<Vec<Rib<'ra>>>>,
1436 ignore_binding: Option<NameBinding<'ra>>,
1437 ignore_import: Option<Import<'ra>>,
1438 ) -> PathResult<'ra> {
1439 let mut module = None;
1440 let mut module_had_parse_errors = false;
1441 let mut allow_super = true;
1442 let mut second_binding = None;
1443
1444 // We'll provide more context to the privacy errors later, up to `len`.
1445 let privacy_errors_len = self.privacy_errors.len();
1446
1447 for (segment_idx, &Segment { ident, id, .. }) in path.iter().enumerate() {
1448 debug!("resolve_path ident {} {:?} {:?}", segment_idx, ident, id);
1449 let record_segment_res = |this: &mut Self, res| {
1450 if finalize.is_some()
1451 && let Some(id) = id
1452 && !this.partial_res_map.contains_key(&id)
1453 {
1454 assert!(id != ast::DUMMY_NODE_ID, "Trying to resolve dummy id");
1455 this.record_partial_res(id, PartialRes::new(res));
1456 }
1457 };
1458
1459 let is_last = segment_idx + 1 == path.len();
1460 let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };
1461 let name = ident.name;
1462
1463 allow_super &= ns == TypeNS && (name == kw::SelfLower || name == kw::Super);
1464
1465 if ns == TypeNS {
1466 if allow_super && name == kw::Super {
1467 let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();
1468 let self_module = match segment_idx {
1469 0 => Some(self.resolve_self(&mut ctxt, parent_scope.module)),
1470 _ => match module {
1471 Some(ModuleOrUniformRoot::Module(module)) => Some(module),
1472 _ => None,
1473 },
1474 };
1475 if let Some(self_module) = self_module
1476 && let Some(parent) = self_module.parent
1477 {
1478 module =
1479 Some(ModuleOrUniformRoot::Module(self.resolve_self(&mut ctxt, parent)));
1480 continue;
1481 }
1482 return PathResult::failed(
1483 ident,
1484 false,
1485 finalize.is_some(),
1486 module_had_parse_errors,
1487 module,
1488 || ("there are too many leading `super` keywords".to_string(), None),
1489 );
1490 }
1491 if segment_idx == 0 {
1492 if name == kw::SelfLower {
1493 let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();
1494 let self_mod = self.resolve_self(&mut ctxt, parent_scope.module);
1495 if let Some(res) = self_mod.res() {
1496 record_segment_res(self, res);
1497 }
1498 module = Some(ModuleOrUniformRoot::Module(self_mod));
1499 continue;
1500 }
1501 if name == kw::PathRoot && ident.span.at_least_rust_2018() {
1502 module = Some(ModuleOrUniformRoot::ExternPrelude);
1503 continue;
1504 }
1505 if name == kw::PathRoot
1506 && ident.span.is_rust_2015()
1507 && self.tcx.sess.at_least_rust_2018()
1508 {
1509 // `::a::b` from 2015 macro on 2018 global edition
1510 module = Some(ModuleOrUniformRoot::CrateRootAndExternPrelude);
1511 continue;
1512 }
1513 if name == kw::PathRoot || name == kw::Crate || name == kw::DollarCrate {
1514 // `::a::b`, `crate::a::b` or `$crate::a::b`
1515 let crate_root = self.resolve_crate_root(ident);
1516 if let Some(res) = crate_root.res() {
1517 record_segment_res(self, res);
1518 }
1519 module = Some(ModuleOrUniformRoot::Module(crate_root));
1520 continue;
1521 }
1522 }
1523 }
1524
1525 // Report special messages for path segment keywords in wrong positions.
1526 if ident.is_path_segment_keyword() && segment_idx != 0 {
1527 return PathResult::failed(
1528 ident,
1529 false,
1530 finalize.is_some(),
1531 module_had_parse_errors,
1532 module,
1533 || {
1534 let name_str = if name == kw::PathRoot {
1535 "crate root".to_string()
1536 } else {
1537 format!("`{name}`")
1538 };
1539 let label = if segment_idx == 1 && path[0].ident.name == kw::PathRoot {
1540 format!("global paths cannot start with {name_str}")
1541 } else {
1542 format!("{name_str} in paths can only be used in start position")
1543 };
1544 (label, None)
1545 },
1546 );
1547 }
1548
1549 let binding = if let Some(module) = module {
1550 self.resolve_ident_in_module(
1551 module,
1552 ident,
1553 ns,
1554 parent_scope,
1555 finalize,
1556 ignore_binding,
1557 ignore_import,
1558 )
1559 .map_err(|(determinacy, _)| determinacy)
1560 } else if let Some(ribs) = ribs
1561 && let Some(TypeNS | ValueNS) = opt_ns
1562 {
1563 assert!(ignore_import.is_none());
1564 match self.resolve_ident_in_lexical_scope(
1565 ident,
1566 ns,
1567 parent_scope,
1568 finalize,
1569 &ribs[ns],
1570 ignore_binding,
1571 ) {
1572 // we found a locally-imported or available item/module
1573 Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
1574 // we found a local variable or type param
1575 Some(LexicalScopeBinding::Res(res)) => {
1576 record_segment_res(self, res);
1577 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1578 res,
1579 path.len() - 1,
1580 ));
1581 }
1582 _ => Err(Determinacy::determined(finalize.is_some())),
1583 }
1584 } else {
1585 self.early_resolve_ident_in_lexical_scope(
1586 ident,
1587 ScopeSet::All(ns),
1588 parent_scope,
1589 finalize,
1590 finalize.is_some(),
1591 ignore_binding,
1592 ignore_import,
1593 )
1594 };
1595
1596 match binding {
1597 Ok(binding) => {
1598 if segment_idx == 1 {
1599 second_binding = Some(binding);
1600 }
1601 let res = binding.res();
1602
1603 // Mark every privacy error in this path with the res to the last element. This allows us
1604 // to detect the item the user cares about and either find an alternative import, or tell
1605 // the user it is not accessible.
1606 for error in &mut self.privacy_errors[privacy_errors_len..] {
1607 error.outermost_res = Some((res, ident));
1608 }
1609
1610 let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(res);
1611 if let Some(next_module) = binding.module() {
1612 if self.mods_with_parse_errors.contains(&next_module.def_id()) {
1613 module_had_parse_errors = true;
1614 }
1615 module = Some(ModuleOrUniformRoot::Module(next_module));
1616 record_segment_res(self, res);
1617 } else if res == Res::ToolMod && !is_last && opt_ns.is_some() {
1618 if binding.is_import() {
1619 self.dcx().emit_err(errors::ToolModuleImported {
1620 span: ident.span,
1621 import: binding.span,
1622 });
1623 }
1624 let res = Res::NonMacroAttr(NonMacroAttrKind::Tool);
1625 return PathResult::NonModule(PartialRes::new(res));
1626 } else if res == Res::Err {
1627 return PathResult::NonModule(PartialRes::new(Res::Err));
1628 } else if opt_ns.is_some() && (is_last || maybe_assoc) {
1629 self.lint_if_path_starts_with_module(finalize, path, second_binding);
1630 record_segment_res(self, res);
1631 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1632 res,
1633 path.len() - segment_idx - 1,
1634 ));
1635 } else {
1636 return PathResult::failed(
1637 ident,
1638 is_last,
1639 finalize.is_some(),
1640 module_had_parse_errors,
1641 module,
1642 || {
1643 let label = format!(
1644 "`{ident}` is {} {}, not a module",
1645 res.article(),
1646 res.descr()
1647 );
1648 (label, None)
1649 },
1650 );
1651 }
1652 }
1653 Err(Undetermined) => return PathResult::Indeterminate,
1654 Err(Determined) => {
1655 if let Some(ModuleOrUniformRoot::Module(module)) = module
1656 && opt_ns.is_some()
1657 && !module.is_normal()
1658 {
1659 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1660 module.res().unwrap(),
1661 path.len() - segment_idx,
1662 ));
1663 }
1664
1665 return PathResult::failed(
1666 ident,
1667 is_last,
1668 finalize.is_some(),
1669 module_had_parse_errors,
1670 module,
1671 || {
1672 self.report_path_resolution_error(
1673 path,
1674 opt_ns,
1675 parent_scope,
1676 ribs,
1677 ignore_binding,
1678 ignore_import,
1679 module,
1680 segment_idx,
1681 ident,
1682 )
1683 },
1684 );
1685 }
1686 }
1687 }
1688
1689 self.lint_if_path_starts_with_module(finalize, path, second_binding);
1690
1691 PathResult::Module(match module {
1692 Some(module) => module,
1693 None if path.is_empty() => ModuleOrUniformRoot::CurrentScope,
1694 _ => bug!("resolve_path: non-empty path `{:?}` has no module", path),
1695 })
1696 }
1697}