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 // or in a const param ty.
1122 if let RibKind::ForwardGenericParamBan(reason) = all_ribs[rib_index].kind {
1123 if let Some(span) = finalize {
1124 let res_error = if rib_ident.name == kw::SelfUpper {
1125 ResolutionError::ForwardDeclaredSelf(reason)
1126 } else {
1127 ResolutionError::ForwardDeclaredGenericParam(rib_ident.name, reason)
1128 };
1129 self.report_error(span, res_error);
1130 }
1131 assert_eq!(res, Res::Err);
1132 return Res::Err;
1133 }
1134
1135 match res {
1136 Res::Local(_) => {
1137 use ResolutionError::*;
1138 let mut res_err = None;
1139
1140 for rib in ribs {
1141 match rib.kind {
1142 RibKind::Normal
1143 | RibKind::FnOrCoroutine
1144 | RibKind::Module(..)
1145 | RibKind::MacroDefinition(..)
1146 | RibKind::ForwardGenericParamBan(_) => {
1147 // Nothing to do. Continue.
1148 }
1149 RibKind::Item(..) | RibKind::AssocItem => {
1150 // This was an attempt to access an upvar inside a
1151 // named function item. This is not allowed, so we
1152 // report an error.
1153 if let Some(span) = finalize {
1154 // We don't immediately trigger a resolve error, because
1155 // we want certain other resolution errors (namely those
1156 // emitted for `ConstantItemRibKind` below) to take
1157 // precedence.
1158 res_err = Some((span, CannotCaptureDynamicEnvironmentInFnItem));
1159 }
1160 }
1161 RibKind::ConstantItem(_, item) => {
1162 // Still doesn't deal with upvars
1163 if let Some(span) = finalize {
1164 let (span, resolution_error) = match item {
1165 None if rib_ident.name == kw::SelfLower => {
1166 (span, LowercaseSelf)
1167 }
1168 None => {
1169 // If we have a `let name = expr;`, we have the span for
1170 // `name` and use that to see if it is followed by a type
1171 // specifier. If not, then we know we need to suggest
1172 // `const name: Ty = expr;`. This is a heuristic, it will
1173 // break down in the presence of macros.
1174 let sm = self.tcx.sess.source_map();
1175 let type_span = match sm.span_look_ahead(
1176 original_rib_ident_def.span,
1177 ":",
1178 None,
1179 ) {
1180 None => {
1181 Some(original_rib_ident_def.span.shrink_to_hi())
1182 }
1183 Some(_) => None,
1184 };
1185 (
1186 rib_ident.span,
1187 AttemptToUseNonConstantValueInConstant {
1188 ident: original_rib_ident_def,
1189 suggestion: "const",
1190 current: "let",
1191 type_span,
1192 },
1193 )
1194 }
1195 Some((ident, kind)) => (
1196 span,
1197 AttemptToUseNonConstantValueInConstant {
1198 ident,
1199 suggestion: "let",
1200 current: kind.as_str(),
1201 type_span: None,
1202 },
1203 ),
1204 };
1205 self.report_error(span, resolution_error);
1206 }
1207 return Res::Err;
1208 }
1209 RibKind::ConstParamTy => {
1210 if let Some(span) = finalize {
1211 self.report_error(
1212 span,
1213 ParamInTyOfConstParam { name: rib_ident.name },
1214 );
1215 }
1216 return Res::Err;
1217 }
1218 RibKind::InlineAsmSym => {
1219 if let Some(span) = finalize {
1220 self.report_error(span, InvalidAsmSym);
1221 }
1222 return Res::Err;
1223 }
1224 }
1225 }
1226 if let Some((span, res_err)) = res_err {
1227 self.report_error(span, res_err);
1228 return Res::Err;
1229 }
1230 }
1231 Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {
1232 for rib in ribs {
1233 let (has_generic_params, def_kind) = match rib.kind {
1234 RibKind::Normal
1235 | RibKind::FnOrCoroutine
1236 | RibKind::Module(..)
1237 | RibKind::MacroDefinition(..)
1238 | RibKind::InlineAsmSym
1239 | RibKind::AssocItem
1240 | RibKind::ForwardGenericParamBan(_) => {
1241 // Nothing to do. Continue.
1242 continue;
1243 }
1244
1245 RibKind::ConstParamTy => {
1246 if !self.tcx.features().generic_const_parameter_types() {
1247 if let Some(span) = finalize {
1248 self.report_error(
1249 span,
1250 ResolutionError::ParamInTyOfConstParam {
1251 name: rib_ident.name,
1252 },
1253 );
1254 }
1255 return Res::Err;
1256 } else {
1257 continue;
1258 }
1259 }
1260
1261 RibKind::ConstantItem(trivial, _) => {
1262 if let ConstantHasGenerics::No(cause) = trivial {
1263 // HACK(min_const_generics): If we encounter `Self` in an anonymous
1264 // constant we can't easily tell if it's generic at this stage, so
1265 // we instead remember this and then enforce the self type to be
1266 // concrete later on.
1267 if let Res::SelfTyAlias {
1268 alias_to: def,
1269 forbid_generic: _,
1270 is_trait_impl,
1271 } = res
1272 {
1273 res = Res::SelfTyAlias {
1274 alias_to: def,
1275 forbid_generic: true,
1276 is_trait_impl,
1277 }
1278 } else {
1279 if let Some(span) = finalize {
1280 let error = match cause {
1281 NoConstantGenericsReason::IsEnumDiscriminant => {
1282 ResolutionError::ParamInEnumDiscriminant {
1283 name: rib_ident.name,
1284 param_kind: ParamKindInEnumDiscriminant::Type,
1285 }
1286 }
1287 NoConstantGenericsReason::NonTrivialConstArg => {
1288 ResolutionError::ParamInNonTrivialAnonConst {
1289 name: rib_ident.name,
1290 param_kind:
1291 ParamKindInNonTrivialAnonConst::Type,
1292 }
1293 }
1294 };
1295 let _: ErrorGuaranteed = self.report_error(span, error);
1296 }
1297
1298 return Res::Err;
1299 }
1300 }
1301
1302 continue;
1303 }
1304
1305 // This was an attempt to use a type parameter outside its scope.
1306 RibKind::Item(has_generic_params, def_kind) => {
1307 (has_generic_params, def_kind)
1308 }
1309 };
1310
1311 if let Some(span) = finalize {
1312 self.report_error(
1313 span,
1314 ResolutionError::GenericParamsFromOuterItem(
1315 res,
1316 has_generic_params,
1317 def_kind,
1318 ),
1319 );
1320 }
1321 return Res::Err;
1322 }
1323 }
1324 Res::Def(DefKind::ConstParam, _) => {
1325 for rib in ribs {
1326 let (has_generic_params, def_kind) = match rib.kind {
1327 RibKind::Normal
1328 | RibKind::FnOrCoroutine
1329 | RibKind::Module(..)
1330 | RibKind::MacroDefinition(..)
1331 | RibKind::InlineAsmSym
1332 | RibKind::AssocItem
1333 | RibKind::ForwardGenericParamBan(_) => continue,
1334
1335 RibKind::ConstParamTy => {
1336 if !self.tcx.features().generic_const_parameter_types() {
1337 if let Some(span) = finalize {
1338 self.report_error(
1339 span,
1340 ResolutionError::ParamInTyOfConstParam {
1341 name: rib_ident.name,
1342 },
1343 );
1344 }
1345 return Res::Err;
1346 } else {
1347 continue;
1348 }
1349 }
1350
1351 RibKind::ConstantItem(trivial, _) => {
1352 if let ConstantHasGenerics::No(cause) = trivial {
1353 if let Some(span) = finalize {
1354 let error = match cause {
1355 NoConstantGenericsReason::IsEnumDiscriminant => {
1356 ResolutionError::ParamInEnumDiscriminant {
1357 name: rib_ident.name,
1358 param_kind: ParamKindInEnumDiscriminant::Const,
1359 }
1360 }
1361 NoConstantGenericsReason::NonTrivialConstArg => {
1362 ResolutionError::ParamInNonTrivialAnonConst {
1363 name: rib_ident.name,
1364 param_kind: ParamKindInNonTrivialAnonConst::Const {
1365 name: rib_ident.name,
1366 },
1367 }
1368 }
1369 };
1370 self.report_error(span, error);
1371 }
1372
1373 return Res::Err;
1374 }
1375
1376 continue;
1377 }
1378
1379 RibKind::Item(has_generic_params, def_kind) => {
1380 (has_generic_params, def_kind)
1381 }
1382 };
1383
1384 // This was an attempt to use a const parameter outside its scope.
1385 if let Some(span) = finalize {
1386 self.report_error(
1387 span,
1388 ResolutionError::GenericParamsFromOuterItem(
1389 res,
1390 has_generic_params,
1391 def_kind,
1392 ),
1393 );
1394 }
1395 return Res::Err;
1396 }
1397 }
1398 _ => {}
1399 }
1400
1401 res
1402 }
1403
1404 #[instrument(level = "debug", skip(self))]
1405 pub(crate) fn maybe_resolve_path(
1406 &mut self,
1407 path: &[Segment],
1408 opt_ns: Option<Namespace>, // `None` indicates a module path in import
1409 parent_scope: &ParentScope<'ra>,
1410 ignore_import: Option<Import<'ra>>,
1411 ) -> PathResult<'ra> {
1412 self.resolve_path_with_ribs(path, opt_ns, parent_scope, None, None, None, ignore_import)
1413 }
1414
1415 #[instrument(level = "debug", skip(self))]
1416 pub(crate) fn resolve_path(
1417 &mut self,
1418 path: &[Segment],
1419 opt_ns: Option<Namespace>, // `None` indicates a module path in import
1420 parent_scope: &ParentScope<'ra>,
1421 finalize: Option<Finalize>,
1422 ignore_binding: Option<NameBinding<'ra>>,
1423 ignore_import: Option<Import<'ra>>,
1424 ) -> PathResult<'ra> {
1425 self.resolve_path_with_ribs(
1426 path,
1427 opt_ns,
1428 parent_scope,
1429 finalize,
1430 None,
1431 ignore_binding,
1432 ignore_import,
1433 )
1434 }
1435
1436 pub(crate) fn resolve_path_with_ribs(
1437 &mut self,
1438 path: &[Segment],
1439 opt_ns: Option<Namespace>, // `None` indicates a module path in import
1440 parent_scope: &ParentScope<'ra>,
1441 finalize: Option<Finalize>,
1442 ribs: Option<&PerNS<Vec<Rib<'ra>>>>,
1443 ignore_binding: Option<NameBinding<'ra>>,
1444 ignore_import: Option<Import<'ra>>,
1445 ) -> PathResult<'ra> {
1446 let mut module = None;
1447 let mut module_had_parse_errors = false;
1448 let mut allow_super = true;
1449 let mut second_binding = None;
1450
1451 // We'll provide more context to the privacy errors later, up to `len`.
1452 let privacy_errors_len = self.privacy_errors.len();
1453
1454 for (segment_idx, &Segment { ident, id, .. }) in path.iter().enumerate() {
1455 debug!("resolve_path ident {} {:?} {:?}", segment_idx, ident, id);
1456 let record_segment_res = |this: &mut Self, res| {
1457 if finalize.is_some()
1458 && let Some(id) = id
1459 && !this.partial_res_map.contains_key(&id)
1460 {
1461 assert!(id != ast::DUMMY_NODE_ID, "Trying to resolve dummy id");
1462 this.record_partial_res(id, PartialRes::new(res));
1463 }
1464 };
1465
1466 let is_last = segment_idx + 1 == path.len();
1467 let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };
1468 let name = ident.name;
1469
1470 allow_super &= ns == TypeNS && (name == kw::SelfLower || name == kw::Super);
1471
1472 if ns == TypeNS {
1473 if allow_super && name == kw::Super {
1474 let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();
1475 let self_module = match segment_idx {
1476 0 => Some(self.resolve_self(&mut ctxt, parent_scope.module)),
1477 _ => match module {
1478 Some(ModuleOrUniformRoot::Module(module)) => Some(module),
1479 _ => None,
1480 },
1481 };
1482 if let Some(self_module) = self_module
1483 && let Some(parent) = self_module.parent
1484 {
1485 module =
1486 Some(ModuleOrUniformRoot::Module(self.resolve_self(&mut ctxt, parent)));
1487 continue;
1488 }
1489 return PathResult::failed(
1490 ident,
1491 false,
1492 finalize.is_some(),
1493 module_had_parse_errors,
1494 module,
1495 || ("there are too many leading `super` keywords".to_string(), None),
1496 );
1497 }
1498 if segment_idx == 0 {
1499 if name == kw::SelfLower {
1500 let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();
1501 let self_mod = self.resolve_self(&mut ctxt, parent_scope.module);
1502 if let Some(res) = self_mod.res() {
1503 record_segment_res(self, res);
1504 }
1505 module = Some(ModuleOrUniformRoot::Module(self_mod));
1506 continue;
1507 }
1508 if name == kw::PathRoot && ident.span.at_least_rust_2018() {
1509 module = Some(ModuleOrUniformRoot::ExternPrelude);
1510 continue;
1511 }
1512 if name == kw::PathRoot
1513 && ident.span.is_rust_2015()
1514 && self.tcx.sess.at_least_rust_2018()
1515 {
1516 // `::a::b` from 2015 macro on 2018 global edition
1517 module = Some(ModuleOrUniformRoot::CrateRootAndExternPrelude);
1518 continue;
1519 }
1520 if name == kw::PathRoot || name == kw::Crate || name == kw::DollarCrate {
1521 // `::a::b`, `crate::a::b` or `$crate::a::b`
1522 let crate_root = self.resolve_crate_root(ident);
1523 if let Some(res) = crate_root.res() {
1524 record_segment_res(self, res);
1525 }
1526 module = Some(ModuleOrUniformRoot::Module(crate_root));
1527 continue;
1528 }
1529 }
1530 }
1531
1532 // Report special messages for path segment keywords in wrong positions.
1533 if ident.is_path_segment_keyword() && segment_idx != 0 {
1534 return PathResult::failed(
1535 ident,
1536 false,
1537 finalize.is_some(),
1538 module_had_parse_errors,
1539 module,
1540 || {
1541 let name_str = if name == kw::PathRoot {
1542 "crate root".to_string()
1543 } else {
1544 format!("`{name}`")
1545 };
1546 let label = if segment_idx == 1 && path[0].ident.name == kw::PathRoot {
1547 format!("global paths cannot start with {name_str}")
1548 } else {
1549 format!("{name_str} in paths can only be used in start position")
1550 };
1551 (label, None)
1552 },
1553 );
1554 }
1555
1556 let binding = if let Some(module) = module {
1557 self.resolve_ident_in_module(
1558 module,
1559 ident,
1560 ns,
1561 parent_scope,
1562 finalize,
1563 ignore_binding,
1564 ignore_import,
1565 )
1566 .map_err(|(determinacy, _)| determinacy)
1567 } else if let Some(ribs) = ribs
1568 && let Some(TypeNS | ValueNS) = opt_ns
1569 {
1570 assert!(ignore_import.is_none());
1571 match self.resolve_ident_in_lexical_scope(
1572 ident,
1573 ns,
1574 parent_scope,
1575 finalize,
1576 &ribs[ns],
1577 ignore_binding,
1578 ) {
1579 // we found a locally-imported or available item/module
1580 Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
1581 // we found a local variable or type param
1582 Some(LexicalScopeBinding::Res(res)) => {
1583 record_segment_res(self, res);
1584 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1585 res,
1586 path.len() - 1,
1587 ));
1588 }
1589 _ => Err(Determinacy::determined(finalize.is_some())),
1590 }
1591 } else {
1592 self.early_resolve_ident_in_lexical_scope(
1593 ident,
1594 ScopeSet::All(ns),
1595 parent_scope,
1596 finalize,
1597 finalize.is_some(),
1598 ignore_binding,
1599 ignore_import,
1600 )
1601 };
1602
1603 match binding {
1604 Ok(binding) => {
1605 if segment_idx == 1 {
1606 second_binding = Some(binding);
1607 }
1608 let res = binding.res();
1609
1610 // Mark every privacy error in this path with the res to the last element. This allows us
1611 // to detect the item the user cares about and either find an alternative import, or tell
1612 // the user it is not accessible.
1613 for error in &mut self.privacy_errors[privacy_errors_len..] {
1614 error.outermost_res = Some((res, ident));
1615 }
1616
1617 let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(res);
1618 if let Some(next_module) = binding.module() {
1619 if self.mods_with_parse_errors.contains(&next_module.def_id()) {
1620 module_had_parse_errors = true;
1621 }
1622 module = Some(ModuleOrUniformRoot::Module(next_module));
1623 record_segment_res(self, res);
1624 } else if res == Res::ToolMod && !is_last && opt_ns.is_some() {
1625 if binding.is_import() {
1626 self.dcx().emit_err(errors::ToolModuleImported {
1627 span: ident.span,
1628 import: binding.span,
1629 });
1630 }
1631 let res = Res::NonMacroAttr(NonMacroAttrKind::Tool);
1632 return PathResult::NonModule(PartialRes::new(res));
1633 } else if res == Res::Err {
1634 return PathResult::NonModule(PartialRes::new(Res::Err));
1635 } else if opt_ns.is_some() && (is_last || maybe_assoc) {
1636 self.lint_if_path_starts_with_module(finalize, path, second_binding);
1637 record_segment_res(self, res);
1638 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1639 res,
1640 path.len() - segment_idx - 1,
1641 ));
1642 } else {
1643 return PathResult::failed(
1644 ident,
1645 is_last,
1646 finalize.is_some(),
1647 module_had_parse_errors,
1648 module,
1649 || {
1650 let label = format!(
1651 "`{ident}` is {} {}, not a module",
1652 res.article(),
1653 res.descr()
1654 );
1655 (label, None)
1656 },
1657 );
1658 }
1659 }
1660 Err(Undetermined) => return PathResult::Indeterminate,
1661 Err(Determined) => {
1662 if let Some(ModuleOrUniformRoot::Module(module)) = module
1663 && opt_ns.is_some()
1664 && !module.is_normal()
1665 {
1666 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1667 module.res().unwrap(),
1668 path.len() - segment_idx,
1669 ));
1670 }
1671
1672 return PathResult::failed(
1673 ident,
1674 is_last,
1675 finalize.is_some(),
1676 module_had_parse_errors,
1677 module,
1678 || {
1679 self.report_path_resolution_error(
1680 path,
1681 opt_ns,
1682 parent_scope,
1683 ribs,
1684 ignore_binding,
1685 ignore_import,
1686 module,
1687 segment_idx,
1688 ident,
1689 )
1690 },
1691 );
1692 }
1693 }
1694 }
1695
1696 self.lint_if_path_starts_with_module(finalize, path, second_binding);
1697
1698 PathResult::Module(match module {
1699 Some(module) => module,
1700 None if path.is_empty() => ModuleOrUniformRoot::CurrentScope,
1701 _ => bug!("resolve_path: non-empty path `{:?}` has no module", path),
1702 })
1703 }
1704}