1use Determinacy::*;
2use Namespace::*;
3use rustc_ast::{self as ast, NodeId};
4use rustc_errors::ErrorGuaranteed;
5use rustc_hir::def::{DefKind, MacroKinds, Namespace, NonMacroAttrKind, PartialRes, PerNS};
6use rustc_middle::bug;
7use rustc_session::lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK;
8use rustc_session::parse::feature_err;
9use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext};
10use rustc_span::{Ident, Span, kw, sym};
11use tracing::{debug, instrument};
12
13use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
14use crate::imports::{Import, NameResolution};
15use crate::late::{ConstantHasGenerics, NoConstantGenericsReason, PathSource, Rib, RibKind};
16use crate::macros::{MacroRulesScope, sub_namespace_match};
17use crate::{
18 AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingKey, CmResolver, Determinacy,
19 Finalize, ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot,
20 NameBinding, NameBindingKind, ParentScope, PathResult, PrivacyError, Res, ResolutionError,
21 Resolver, Scope, ScopeSet, Segment, Stage, Used, Weak, errors,
22};
23
24#[derive(Copy, Clone)]
25pub enum UsePrelude {
26 No,
27 Yes,
28}
29
30impl From<UsePrelude> for bool {
31 fn from(up: UsePrelude) -> bool {
32 matches!(up, UsePrelude::Yes)
33 }
34}
35
36#[derive(Debug, PartialEq, Clone, Copy)]
37enum Shadowing {
38 Restricted,
39 Unrestricted,
40}
41
42impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
43 pub(crate) fn visit_scopes<'r, T>(
47 mut self: CmResolver<'r, 'ra, 'tcx>,
48 scope_set: ScopeSet<'ra>,
49 parent_scope: &ParentScope<'ra>,
50 ctxt: SyntaxContext,
51 derive_fallback_lint_id: Option<NodeId>,
52 mut visitor: impl FnMut(
53 &mut CmResolver<'r, 'ra, 'tcx>,
54 Scope<'ra>,
55 UsePrelude,
56 SyntaxContext,
57 ) -> Option<T>,
58 ) -> Option<T> {
59 let rust_2015 = ctxt.edition().is_rust_2015();
101 let (ns, macro_kind) = match scope_set {
102 ScopeSet::All(ns) | ScopeSet::ModuleAndExternPrelude(ns, _) => (ns, None),
103 ScopeSet::ExternPrelude => (TypeNS, None),
104 ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
105 };
106 let module = match scope_set {
107 ScopeSet::ModuleAndExternPrelude(_, module) => module,
109 _ => parent_scope.module.nearest_item_scope(),
111 };
112 let module_and_extern_prelude = matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..));
113 let extern_prelude = matches!(scope_set, ScopeSet::ExternPrelude);
114 let mut scope = match ns {
115 _ if module_and_extern_prelude => Scope::Module(module, None),
116 _ if extern_prelude => Scope::ExternPreludeItems,
117 TypeNS | ValueNS => Scope::Module(module, None),
118 MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
119 };
120 let mut ctxt = ctxt.normalize_to_macros_2_0();
121 let mut use_prelude = !module.no_implicit_prelude;
122
123 loop {
124 let visit = match scope {
125 Scope::DeriveHelpers(expn_id) => {
127 !(expn_id == parent_scope.expansion && macro_kind == Some(MacroKind::Derive))
128 }
129 Scope::DeriveHelpersCompat => true,
130 Scope::MacroRules(macro_rules_scope) => {
131 while let MacroRulesScope::Invocation(invoc_id) = macro_rules_scope.get() {
136 if let Some(next_scope) = self.output_macro_rules_scopes.get(&invoc_id) {
137 macro_rules_scope.set(next_scope.get());
138 } else {
139 break;
140 }
141 }
142 true
143 }
144 Scope::Module(..) => true,
145 Scope::MacroUsePrelude => use_prelude || rust_2015,
146 Scope::BuiltinAttrs => true,
147 Scope::ExternPreludeItems | Scope::ExternPreludeFlags => {
148 use_prelude || module_and_extern_prelude || extern_prelude
149 }
150 Scope::ToolPrelude => use_prelude,
151 Scope::StdLibPrelude => use_prelude || ns == MacroNS,
152 Scope::BuiltinTypes => true,
153 };
154
155 if visit {
156 let use_prelude = if use_prelude { UsePrelude::Yes } else { UsePrelude::No };
157 if let break_result @ Some(..) = visitor(&mut self, scope, use_prelude, ctxt) {
158 return break_result;
159 }
160 }
161
162 scope = match scope {
163 Scope::DeriveHelpers(LocalExpnId::ROOT) => Scope::DeriveHelpersCompat,
164 Scope::DeriveHelpers(expn_id) => {
165 let expn_data = expn_id.expn_data();
167 match expn_data.kind {
168 ExpnKind::Root
169 | ExpnKind::Macro(MacroKind::Bang | MacroKind::Derive, _) => {
170 Scope::DeriveHelpersCompat
171 }
172 _ => Scope::DeriveHelpers(expn_data.parent.expect_local()),
173 }
174 }
175 Scope::DeriveHelpersCompat => Scope::MacroRules(parent_scope.macro_rules),
176 Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() {
177 MacroRulesScope::Binding(binding) => {
178 Scope::MacroRules(binding.parent_macro_rules_scope)
179 }
180 MacroRulesScope::Invocation(invoc_id) => {
181 Scope::MacroRules(self.invocation_parent_scopes[&invoc_id].macro_rules)
182 }
183 MacroRulesScope::Empty => Scope::Module(module, None),
184 },
185 Scope::Module(..) if module_and_extern_prelude => match ns {
186 TypeNS => {
187 ctxt.adjust(ExpnId::root());
188 Scope::ExternPreludeItems
189 }
190 ValueNS | MacroNS => break,
191 },
192 Scope::Module(module, prev_lint_id) => {
193 use_prelude = !module.no_implicit_prelude;
194 match self.hygienic_lexical_parent(module, &mut ctxt, derive_fallback_lint_id) {
195 Some((parent_module, lint_id)) => {
196 Scope::Module(parent_module, lint_id.or(prev_lint_id))
197 }
198 None => {
199 ctxt.adjust(ExpnId::root());
200 match ns {
201 TypeNS => Scope::ExternPreludeItems,
202 ValueNS => Scope::StdLibPrelude,
203 MacroNS => Scope::MacroUsePrelude,
204 }
205 }
206 }
207 }
208 Scope::MacroUsePrelude => Scope::StdLibPrelude,
209 Scope::BuiltinAttrs => break, Scope::ExternPreludeItems => Scope::ExternPreludeFlags,
211 Scope::ExternPreludeFlags if module_and_extern_prelude || extern_prelude => break,
212 Scope::ExternPreludeFlags => Scope::ToolPrelude,
213 Scope::ToolPrelude => Scope::StdLibPrelude,
214 Scope::StdLibPrelude => match ns {
215 TypeNS => Scope::BuiltinTypes,
216 ValueNS => break, MacroNS => Scope::BuiltinAttrs,
218 },
219 Scope::BuiltinTypes => break, };
221 }
222
223 None
224 }
225
226 fn hygienic_lexical_parent(
227 &self,
228 module: Module<'ra>,
229 ctxt: &mut SyntaxContext,
230 derive_fallback_lint_id: Option<NodeId>,
231 ) -> Option<(Module<'ra>, Option<NodeId>)> {
232 if !module.expansion.outer_expn_is_descendant_of(*ctxt) {
233 return Some((self.expn_def_scope(ctxt.remove_mark()), None));
234 }
235
236 if let ModuleKind::Block = module.kind {
237 return Some((module.parent.unwrap().nearest_item_scope(), None));
238 }
239
240 if derive_fallback_lint_id.is_some()
252 && let Some(parent) = module.parent
253 && module.expansion != parent.expansion
255 && module.expansion.is_descendant_of(parent.expansion)
257 && let Some(def_id) = module.expansion.expn_data().macro_def_id
259 {
260 let ext = &self.get_macro_by_def_id(def_id).ext;
261 if ext.builtin_name.is_none()
262 && ext.macro_kinds() == MacroKinds::DERIVE
263 && parent.expansion.outer_expn_is_descendant_of(*ctxt)
264 {
265 return Some((parent, derive_fallback_lint_id));
266 }
267 }
268
269 None
270 }
271
272 #[instrument(level = "debug", skip(self, ribs))]
290 pub(crate) fn resolve_ident_in_lexical_scope(
291 &mut self,
292 mut ident: Ident,
293 ns: Namespace,
294 parent_scope: &ParentScope<'ra>,
295 finalize: Option<Finalize>,
296 ribs: &[Rib<'ra>],
297 ignore_binding: Option<NameBinding<'ra>>,
298 ) -> Option<LexicalScopeBinding<'ra>> {
299 assert!(ns == TypeNS || ns == ValueNS);
300 let orig_ident = ident;
301 let (general_span, normalized_span) = if ident.name == kw::SelfUpper {
302 let empty_span = ident.span.with_ctxt(SyntaxContext::root());
304 (empty_span, empty_span)
305 } else if ns == TypeNS {
306 let normalized_span = ident.span.normalize_to_macros_2_0();
307 (normalized_span, normalized_span)
308 } else {
309 (ident.span.normalize_to_macro_rules(), ident.span.normalize_to_macros_2_0())
310 };
311 ident.span = general_span;
312 let normalized_ident = Ident { span: normalized_span, ..ident };
313
314 for (i, rib) in ribs.iter().enumerate().rev() {
316 debug!("walk rib\n{:?}", rib.bindings);
317 let rib_ident = if rib.kind.contains_params() { normalized_ident } else { ident };
320 if let Some((original_rib_ident_def, res)) = rib.bindings.get_key_value(&rib_ident) {
321 return Some(LexicalScopeBinding::Res(self.validate_res_from_ribs(
323 i,
324 rib_ident,
325 *res,
326 finalize.map(|finalize| finalize.path_span),
327 *original_rib_ident_def,
328 ribs,
329 )));
330 } else if let RibKind::Block(Some(module)) = rib.kind
331 && let Ok(binding) = self.cm().resolve_ident_in_module_unadjusted(
332 ModuleOrUniformRoot::Module(module),
333 ident,
334 ns,
335 parent_scope,
336 Shadowing::Unrestricted,
337 finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }),
338 ignore_binding,
339 None,
340 )
341 {
342 return Some(LexicalScopeBinding::Item(binding));
344 } else if let RibKind::Module(module) = rib.kind {
345 let parent_scope = &ParentScope { module, ..*parent_scope };
347 let finalize = finalize.map(|f| Finalize { stage: Stage::Late, ..f });
348 return self
349 .cm()
350 .resolve_ident_in_scope_set(
351 orig_ident,
352 ScopeSet::All(ns),
353 parent_scope,
354 finalize,
355 finalize.is_some(),
356 ignore_binding,
357 None,
358 )
359 .ok()
360 .map(LexicalScopeBinding::Item);
361 }
362
363 if let RibKind::MacroDefinition(def) = rib.kind
364 && def == self.macro_def(ident.span.ctxt())
365 {
366 ident.span.remove_mark();
369 }
370 }
371
372 unreachable!()
373 }
374
375 #[instrument(level = "debug", skip(self))]
377 pub(crate) fn resolve_ident_in_scope_set<'r>(
378 self: CmResolver<'r, 'ra, 'tcx>,
379 orig_ident: Ident,
380 scope_set: ScopeSet<'ra>,
381 parent_scope: &ParentScope<'ra>,
382 finalize: Option<Finalize>,
383 force: bool,
384 ignore_binding: Option<NameBinding<'ra>>,
385 ignore_import: Option<Import<'ra>>,
386 ) -> Result<NameBinding<'ra>, Determinacy> {
387 bitflags::bitflags! {
388 #[derive(Clone, Copy)]
389 struct Flags: u8 {
390 const MACRO_RULES = 1 << 0;
391 const MODULE = 1 << 1;
392 const MISC_SUGGEST_CRATE = 1 << 2;
393 const MISC_SUGGEST_SELF = 1 << 3;
394 const MISC_FROM_PRELUDE = 1 << 4;
395 }
396 }
397
398 assert!(force || finalize.is_none()); if orig_ident.is_path_segment_keyword() {
402 return Err(Determinacy::Determined);
403 }
404
405 let (ns, macro_kind) = match scope_set {
406 ScopeSet::All(ns) | ScopeSet::ModuleAndExternPrelude(ns, _) => (ns, None),
407 ScopeSet::ExternPrelude => (TypeNS, None),
408 ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
409 };
410
411 let mut innermost_result: Option<(NameBinding<'_>, Flags)> = None;
423 let mut determinacy = Determinacy::Determined;
424 let mut extern_prelude_item_binding = None;
425 let mut extern_prelude_flag_binding = None;
426 macro finalize_scope() {
428 if innermost_result.is_none() { finalize } else { None }
429 }
430
431 let derive_fallback_lint_id = match finalize {
433 Some(Finalize { node_id, stage: Stage::Late, .. }) => Some(node_id),
434 _ => None,
435 };
436 let break_result = self.visit_scopes(
437 scope_set,
438 parent_scope,
439 orig_ident.span.ctxt(),
440 derive_fallback_lint_id,
441 |this, scope, use_prelude, ctxt| {
442 let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt));
443 let result = match scope {
444 Scope::DeriveHelpers(expn_id) => {
445 if let Some(binding) = this.helper_attrs.get(&expn_id).and_then(|attrs| {
446 attrs.iter().rfind(|(i, _)| ident == *i).map(|(_, binding)| *binding)
447 }) {
448 Ok((binding, Flags::empty()))
449 } else {
450 Err(Determinacy::Determined)
451 }
452 }
453 Scope::DeriveHelpersCompat => {
454 let mut result = Err(Determinacy::Determined);
455 for derive in parent_scope.derives {
456 let parent_scope = &ParentScope { derives: &[], ..*parent_scope };
457 match this.reborrow().resolve_macro_path(
458 derive,
459 MacroKind::Derive,
460 parent_scope,
461 true,
462 force,
463 ignore_import,
464 None,
465 ) {
466 Ok((Some(ext), _)) => {
467 if ext.helper_attrs.contains(&ident.name) {
468 let binding = this.arenas.new_pub_res_binding(
469 Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat),
470 derive.span,
471 LocalExpnId::ROOT,
472 );
473 result = Ok((binding, Flags::empty()));
474 break;
475 }
476 }
477 Ok(_) | Err(Determinacy::Determined) => {}
478 Err(Determinacy::Undetermined) => {
479 result = Err(Determinacy::Undetermined)
480 }
481 }
482 }
483 result
484 }
485 Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() {
486 MacroRulesScope::Binding(macro_rules_binding)
487 if ident == macro_rules_binding.ident =>
488 {
489 Ok((macro_rules_binding.binding, Flags::MACRO_RULES))
490 }
491 MacroRulesScope::Invocation(_) => Err(Determinacy::Undetermined),
492 _ => Err(Determinacy::Determined),
493 },
494 Scope::Module(module, derive_fallback_lint_id) => {
495 let (adjusted_parent_scope, adjusted_finalize) =
496 if matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..)) {
497 (parent_scope, finalize_scope!())
498 } else {
499 (
500 &ParentScope { module, ..*parent_scope },
501 finalize_scope!().map(|f| Finalize { used: Used::Scope, ..f }),
502 )
503 };
504 let binding = this.reborrow().resolve_ident_in_module_unadjusted(
505 ModuleOrUniformRoot::Module(module),
506 ident,
507 ns,
508 adjusted_parent_scope,
509 Shadowing::Restricted,
510 adjusted_finalize,
511 ignore_binding,
512 ignore_import,
513 );
514 match binding {
515 Ok(binding) => {
516 if let Some(lint_id) = derive_fallback_lint_id {
517 this.get_mut().lint_buffer.buffer_lint(
518 PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
519 lint_id,
520 orig_ident.span,
521 errors::ProcMacroDeriveResolutionFallback {
522 span: orig_ident.span,
523 ns_descr: ns.descr(),
524 ident,
525 },
526 );
527 }
528 let misc_flags = if module == this.graph_root {
529 Flags::MISC_SUGGEST_CRATE
530 } else if module.is_normal() {
531 Flags::MISC_SUGGEST_SELF
532 } else {
533 Flags::empty()
534 };
535 Ok((binding, Flags::MODULE | misc_flags))
536 }
537 Err((Determinacy::Undetermined, Weak::No)) => {
538 return Some(Err(Determinacy::determined(force)));
539 }
540 Err((Determinacy::Undetermined, Weak::Yes)) => {
541 Err(Determinacy::Undetermined)
542 }
543 Err((Determinacy::Determined, _)) => Err(Determinacy::Determined),
544 }
545 }
546 Scope::MacroUsePrelude => {
547 match this.macro_use_prelude.get(&ident.name).cloned() {
548 Some(binding) => Ok((binding, Flags::MISC_FROM_PRELUDE)),
549 None => Err(Determinacy::determined(
550 this.graph_root.unexpanded_invocations.borrow().is_empty(),
551 )),
552 }
553 }
554 Scope::BuiltinAttrs => match this.builtin_attrs_bindings.get(&ident.name) {
555 Some(binding) => Ok((*binding, Flags::empty())),
556 None => Err(Determinacy::Determined),
557 },
558 Scope::ExternPreludeItems => {
559 match this
560 .reborrow()
561 .extern_prelude_get_item(ident, finalize_scope!().is_some())
562 {
563 Some(binding) => {
564 extern_prelude_item_binding = Some(binding);
565 Ok((binding, Flags::empty()))
566 }
567 None => Err(Determinacy::determined(
568 this.graph_root.unexpanded_invocations.borrow().is_empty(),
569 )),
570 }
571 }
572 Scope::ExternPreludeFlags => {
573 match this.extern_prelude_get_flag(ident, finalize_scope!().is_some()) {
574 Some(binding) => {
575 extern_prelude_flag_binding = Some(binding);
576 Ok((binding, Flags::empty()))
577 }
578 None => Err(Determinacy::Determined),
579 }
580 }
581 Scope::ToolPrelude => match this.registered_tool_bindings.get(&ident) {
582 Some(binding) => Ok((*binding, Flags::empty())),
583 None => Err(Determinacy::Determined),
584 },
585 Scope::StdLibPrelude => {
586 let mut result = Err(Determinacy::Determined);
587 if let Some(prelude) = this.prelude
588 && let Ok(binding) = this.reborrow().resolve_ident_in_module_unadjusted(
589 ModuleOrUniformRoot::Module(prelude),
590 ident,
591 ns,
592 parent_scope,
593 Shadowing::Unrestricted,
594 None,
595 ignore_binding,
596 ignore_import,
597 )
598 && (matches!(use_prelude, UsePrelude::Yes)
599 || this.is_builtin_macro(binding.res()))
600 {
601 result = Ok((binding, Flags::MISC_FROM_PRELUDE));
602 }
603
604 result
605 }
606 Scope::BuiltinTypes => match this.builtin_types_bindings.get(&ident.name) {
607 Some(binding) => {
608 if matches!(ident.name, sym::f16)
609 && !this.tcx.features().f16()
610 && !ident.span.allows_unstable(sym::f16)
611 && finalize_scope!().is_some()
612 {
613 feature_err(
614 this.tcx.sess,
615 sym::f16,
616 ident.span,
617 "the type `f16` is unstable",
618 )
619 .emit();
620 }
621 if matches!(ident.name, sym::f128)
622 && !this.tcx.features().f128()
623 && !ident.span.allows_unstable(sym::f128)
624 && finalize_scope!().is_some()
625 {
626 feature_err(
627 this.tcx.sess,
628 sym::f128,
629 ident.span,
630 "the type `f128` is unstable",
631 )
632 .emit();
633 }
634 Ok((*binding, Flags::empty()))
635 }
636 None => Err(Determinacy::Determined),
637 },
638 };
639
640 match result {
641 Ok((binding, flags)) => {
642 if !sub_namespace_match(binding.macro_kinds(), macro_kind) {
643 return None;
644 }
645
646 if matches!(finalize, None | Some(Finalize { stage: Stage::Late, .. })) {
651 return Some(Ok(binding));
652 }
653
654 if let Some((innermost_binding, innermost_flags)) = innermost_result {
655 let (res, innermost_res) = (binding.res(), innermost_binding.res());
657 if res != innermost_res {
658 let is_builtin = |res| {
659 matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Builtin(..)))
660 };
661 let derive_helper =
662 Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
663 let derive_helper_compat =
664 Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat);
665
666 let ambiguity_error_kind = if is_builtin(innermost_res)
667 || is_builtin(res)
668 {
669 Some(AmbiguityKind::BuiltinAttr)
670 } else if innermost_res == derive_helper_compat
671 || res == derive_helper_compat && innermost_res != derive_helper
672 {
673 Some(AmbiguityKind::DeriveHelper)
674 } else if innermost_flags.contains(Flags::MACRO_RULES)
675 && flags.contains(Flags::MODULE)
676 && !this.disambiguate_macro_rules_vs_modularized(
677 innermost_binding,
678 binding,
679 )
680 || flags.contains(Flags::MACRO_RULES)
681 && innermost_flags.contains(Flags::MODULE)
682 && !this.disambiguate_macro_rules_vs_modularized(
683 binding,
684 innermost_binding,
685 )
686 {
687 Some(AmbiguityKind::MacroRulesVsModularized)
688 } else if innermost_binding.is_glob_import() {
689 Some(AmbiguityKind::GlobVsOuter)
690 } else if innermost_binding
691 .may_appear_after(parent_scope.expansion, binding)
692 {
693 Some(AmbiguityKind::MoreExpandedVsOuter)
694 } else {
695 None
696 };
697 let issue_145575_hack = Some(binding)
701 == extern_prelude_flag_binding
702 && extern_prelude_item_binding.is_some()
703 && extern_prelude_item_binding != Some(innermost_binding);
704 if let Some(kind) = ambiguity_error_kind
705 && !issue_145575_hack
706 {
707 let misc = |f: Flags| {
708 if f.contains(Flags::MISC_SUGGEST_CRATE) {
709 AmbiguityErrorMisc::SuggestCrate
710 } else if f.contains(Flags::MISC_SUGGEST_SELF) {
711 AmbiguityErrorMisc::SuggestSelf
712 } else if f.contains(Flags::MISC_FROM_PRELUDE) {
713 AmbiguityErrorMisc::FromPrelude
714 } else {
715 AmbiguityErrorMisc::None
716 }
717 };
718 this.get_mut().ambiguity_errors.push(AmbiguityError {
719 kind,
720 ident: orig_ident,
721 b1: innermost_binding,
722 b2: binding,
723 warning: false,
724 misc1: misc(innermost_flags),
725 misc2: misc(flags),
726 });
727 return Some(Ok(innermost_binding));
728 }
729 }
730 } else {
731 innermost_result = Some((binding, flags));
733 }
734 }
735 Err(Determinacy::Determined) => {}
736 Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined,
737 }
738
739 None
740 },
741 );
742
743 if let Some(break_result) = break_result {
744 return break_result;
745 }
746
747 if let Some((binding, _)) = innermost_result {
749 return Ok(binding);
750 }
751
752 Err(Determinacy::determined(determinacy == Determinacy::Determined || force))
753 }
754
755 #[instrument(level = "debug", skip(self))]
756 pub(crate) fn maybe_resolve_ident_in_module<'r>(
757 self: CmResolver<'r, 'ra, 'tcx>,
758 module: ModuleOrUniformRoot<'ra>,
759 ident: Ident,
760 ns: Namespace,
761 parent_scope: &ParentScope<'ra>,
762 ignore_import: Option<Import<'ra>>,
763 ) -> Result<NameBinding<'ra>, Determinacy> {
764 self.resolve_ident_in_module(module, ident, ns, parent_scope, None, None, ignore_import)
765 .map_err(|(determinacy, _)| determinacy)
766 }
767
768 #[instrument(level = "debug", skip(self))]
769 pub(crate) fn resolve_ident_in_module<'r>(
770 self: CmResolver<'r, 'ra, 'tcx>,
771 module: ModuleOrUniformRoot<'ra>,
772 mut ident: Ident,
773 ns: Namespace,
774 parent_scope: &ParentScope<'ra>,
775 finalize: Option<Finalize>,
776 ignore_binding: Option<NameBinding<'ra>>,
777 ignore_import: Option<Import<'ra>>,
778 ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
779 let tmp_parent_scope;
780 let mut adjusted_parent_scope = parent_scope;
781 match module {
782 ModuleOrUniformRoot::Module(m) => {
783 if let Some(def) = ident.span.normalize_to_macros_2_0_and_adjust(m.expansion) {
784 tmp_parent_scope =
785 ParentScope { module: self.expn_def_scope(def), ..*parent_scope };
786 adjusted_parent_scope = &tmp_parent_scope;
787 }
788 }
789 ModuleOrUniformRoot::ExternPrelude => {
790 ident.span.normalize_to_macros_2_0_and_adjust(ExpnId::root());
791 }
792 ModuleOrUniformRoot::ModuleAndExternPrelude(..) | ModuleOrUniformRoot::CurrentScope => {
793 }
795 }
796 self.resolve_ident_in_module_unadjusted(
797 module,
798 ident,
799 ns,
800 adjusted_parent_scope,
801 Shadowing::Unrestricted,
802 finalize,
803 ignore_binding,
804 ignore_import,
805 )
806 }
807 #[instrument(level = "debug", skip(self))]
810 fn resolve_ident_in_module_unadjusted<'r>(
811 mut self: CmResolver<'r, 'ra, 'tcx>,
812 module: ModuleOrUniformRoot<'ra>,
813 ident: Ident,
814 ns: Namespace,
815 parent_scope: &ParentScope<'ra>,
816 shadowing: Shadowing,
817 finalize: Option<Finalize>,
818 ignore_binding: Option<NameBinding<'ra>>,
821 ignore_import: Option<Import<'ra>>,
822 ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
823 let module = match module {
824 ModuleOrUniformRoot::Module(module) => module,
825 ModuleOrUniformRoot::ModuleAndExternPrelude(module) => {
826 assert_eq!(shadowing, Shadowing::Unrestricted);
827 let binding = self.resolve_ident_in_scope_set(
828 ident,
829 ScopeSet::ModuleAndExternPrelude(ns, module),
830 parent_scope,
831 finalize,
832 finalize.is_some(),
833 ignore_binding,
834 ignore_import,
835 );
836 return binding.map_err(|determinacy| (determinacy, Weak::No));
837 }
838 ModuleOrUniformRoot::ExternPrelude => {
839 assert_eq!(shadowing, Shadowing::Unrestricted);
840 return if ns != TypeNS {
841 Err((Determined, Weak::No))
842 } else {
843 let binding = self.resolve_ident_in_scope_set(
844 ident,
845 ScopeSet::ExternPrelude,
846 parent_scope,
847 finalize,
848 finalize.is_some(),
849 ignore_binding,
850 ignore_import,
851 );
852 return binding.map_err(|determinacy| (determinacy, Weak::No));
853 };
854 }
855 ModuleOrUniformRoot::CurrentScope => {
856 assert_eq!(shadowing, Shadowing::Unrestricted);
857 if ns == TypeNS {
858 if ident.name == kw::Crate || ident.name == kw::DollarCrate {
859 let module = self.resolve_crate_root(ident);
860 return Ok(module.self_binding.unwrap());
861 } else if ident.name == kw::Super || ident.name == kw::SelfLower {
862 }
866 }
867
868 let binding = self.resolve_ident_in_scope_set(
869 ident,
870 ScopeSet::All(ns),
871 parent_scope,
872 finalize,
873 finalize.is_some(),
874 ignore_binding,
875 ignore_import,
876 );
877 return binding.map_err(|determinacy| (determinacy, Weak::No));
878 }
879 };
880
881 let key = BindingKey::new(ident, ns);
882 let resolution = &*self
886 .resolution_or_default(module, key)
887 .try_borrow_mut()
888 .map_err(|_| (Determined, Weak::No))?;
889
890 let binding = [resolution.non_glob_binding, resolution.glob_binding]
895 .into_iter()
896 .find_map(|binding| if binding == ignore_binding { None } else { binding });
897
898 if let Some(finalize) = finalize {
899 return self.get_mut().finalize_module_binding(
900 ident,
901 binding,
902 if resolution.non_glob_binding.is_some() { resolution.glob_binding } else { None },
903 parent_scope,
904 module,
905 finalize,
906 shadowing,
907 );
908 }
909
910 let check_usable = |this: CmResolver<'r, 'ra, 'tcx>, binding: NameBinding<'ra>| {
911 let usable = this.is_accessible_from(binding.vis, parent_scope.module);
912 if usable { Ok(binding) } else { Err((Determined, Weak::No)) }
913 };
914
915 if let Some(binding) = binding
917 && !binding.is_glob_import()
918 {
919 return check_usable(self, binding);
920 }
921
922 if self.reborrow().single_import_can_define_name(
927 &resolution,
928 binding,
929 ns,
930 ignore_import,
931 ignore_binding,
932 parent_scope,
933 ) {
934 return Err((Undetermined, Weak::No));
935 }
936
937 if let Some(binding) = binding {
950 if binding.determined() || ns == MacroNS || shadowing == Shadowing::Restricted {
951 return check_usable(self, binding);
952 } else {
953 return Err((Undetermined, Weak::No));
954 }
955 }
956
957 if !module.unexpanded_invocations.borrow().is_empty() {
968 return Err((Undetermined, Weak::Yes));
969 }
970
971 for glob_import in module.globs.borrow().iter() {
974 if ignore_import == Some(*glob_import) {
975 continue;
976 }
977 if !self.is_accessible_from(glob_import.vis, parent_scope.module) {
978 continue;
979 }
980 let module = match glob_import.imported_module.get() {
981 Some(ModuleOrUniformRoot::Module(module)) => module,
982 Some(_) => continue,
983 None => return Err((Undetermined, Weak::Yes)),
984 };
985 let tmp_parent_scope;
986 let (mut adjusted_parent_scope, mut ident) =
987 (parent_scope, ident.normalize_to_macros_2_0());
988 match ident.span.glob_adjust(module.expansion, glob_import.span) {
989 Some(Some(def)) => {
990 tmp_parent_scope =
991 ParentScope { module: self.expn_def_scope(def), ..*parent_scope };
992 adjusted_parent_scope = &tmp_parent_scope;
993 }
994 Some(None) => {}
995 None => continue,
996 };
997 let result = self.reborrow().resolve_ident_in_module_unadjusted(
998 ModuleOrUniformRoot::Module(module),
999 ident,
1000 ns,
1001 adjusted_parent_scope,
1002 Shadowing::Unrestricted,
1003 None,
1004 ignore_binding,
1005 ignore_import,
1006 );
1007
1008 match result {
1009 Err((Determined, _)) => continue,
1010 Ok(binding)
1011 if !self.is_accessible_from(binding.vis, glob_import.parent_scope.module) =>
1012 {
1013 continue;
1014 }
1015 Ok(_) | Err((Undetermined, _)) => return Err((Undetermined, Weak::Yes)),
1016 }
1017 }
1018
1019 Err((Determined, Weak::No))
1021 }
1022
1023 fn finalize_module_binding(
1024 &mut self,
1025 ident: Ident,
1026 binding: Option<NameBinding<'ra>>,
1027 shadowed_glob: Option<NameBinding<'ra>>,
1028 parent_scope: &ParentScope<'ra>,
1029 module: Module<'ra>,
1030 finalize: Finalize,
1031 shadowing: Shadowing,
1032 ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
1033 let Finalize { path_span, report_private, used, root_span, .. } = finalize;
1034
1035 let Some(binding) = binding else {
1036 return Err((Determined, Weak::No));
1037 };
1038
1039 if !self.is_accessible_from(binding.vis, parent_scope.module) {
1040 if report_private {
1041 self.privacy_errors.push(PrivacyError {
1042 ident,
1043 binding,
1044 dedup_span: path_span,
1045 outermost_res: None,
1046 source: None,
1047 parent_scope: *parent_scope,
1048 single_nested: path_span != root_span,
1049 });
1050 } else {
1051 return Err((Determined, Weak::No));
1052 }
1053 }
1054
1055 if let Some(shadowed_glob) = shadowed_glob
1057 && shadowing == Shadowing::Restricted
1058 && finalize.stage == Stage::Early
1059 && binding.expansion != LocalExpnId::ROOT
1060 && binding.res() != shadowed_glob.res()
1061 {
1062 self.ambiguity_errors.push(AmbiguityError {
1063 kind: AmbiguityKind::GlobVsExpanded,
1064 ident,
1065 b1: binding,
1066 b2: shadowed_glob,
1067 warning: false,
1068 misc1: AmbiguityErrorMisc::None,
1069 misc2: AmbiguityErrorMisc::None,
1070 });
1071 }
1072
1073 if shadowing == Shadowing::Unrestricted
1074 && binding.expansion != LocalExpnId::ROOT
1075 && let NameBindingKind::Import { import, .. } = binding.kind
1076 && matches!(import.kind, ImportKind::MacroExport)
1077 {
1078 self.macro_expanded_macro_export_errors.insert((path_span, binding.span));
1079 }
1080
1081 if let Res::Def(_, def_id) = binding.res() {
1085 let struct_ctor = match def_id.as_local() {
1086 Some(def_id) => self.struct_constructors.get(&def_id).cloned(),
1087 None => {
1088 let ctor = self.cstore().ctor_untracked(def_id);
1089 ctor.map(|(ctor_kind, ctor_def_id)| {
1090 let ctor_res = Res::Def(
1091 DefKind::Ctor(rustc_hir::def::CtorOf::Struct, ctor_kind),
1092 ctor_def_id,
1093 );
1094 let ctor_vis = self.tcx.visibility(ctor_def_id);
1095 let field_visibilities = self
1096 .tcx
1097 .associated_item_def_ids(def_id)
1098 .iter()
1099 .map(|field_id| self.tcx.visibility(field_id))
1100 .collect();
1101 (ctor_res, ctor_vis, field_visibilities)
1102 })
1103 }
1104 };
1105 if let Some((_, _, fields)) = struct_ctor
1106 && fields.iter().any(|vis| !self.is_accessible_from(*vis, module))
1107 {
1108 self.inaccessible_ctor_reexport.insert(path_span, binding.span);
1109 }
1110 }
1111
1112 self.record_use(ident, binding, used);
1113 return Ok(binding);
1114 }
1115
1116 fn single_import_can_define_name<'r>(
1119 mut self: CmResolver<'r, 'ra, 'tcx>,
1120 resolution: &NameResolution<'ra>,
1121 binding: Option<NameBinding<'ra>>,
1122 ns: Namespace,
1123 ignore_import: Option<Import<'ra>>,
1124 ignore_binding: Option<NameBinding<'ra>>,
1125 parent_scope: &ParentScope<'ra>,
1126 ) -> bool {
1127 for single_import in &resolution.single_imports {
1128 if ignore_import == Some(*single_import) {
1129 continue;
1130 }
1131 if !self.is_accessible_from(single_import.vis, parent_scope.module) {
1132 continue;
1133 }
1134 if let Some(ignored) = ignore_binding
1135 && let NameBindingKind::Import { import, .. } = ignored.kind
1136 && import == *single_import
1137 {
1138 continue;
1139 }
1140
1141 let Some(module) = single_import.imported_module.get() else {
1142 return true;
1143 };
1144 let ImportKind::Single { source, target, bindings, .. } = &single_import.kind else {
1145 unreachable!();
1146 };
1147 if source != target {
1148 if bindings.iter().all(|binding| binding.get().binding().is_none()) {
1149 return true;
1150 } else if bindings[ns].get().binding().is_none() && binding.is_some() {
1151 return true;
1152 }
1153 }
1154
1155 match self.reborrow().resolve_ident_in_module(
1156 module,
1157 *source,
1158 ns,
1159 &single_import.parent_scope,
1160 None,
1161 ignore_binding,
1162 ignore_import,
1163 ) {
1164 Err((Determined, _)) => continue,
1165 Ok(binding)
1166 if !self.is_accessible_from(binding.vis, single_import.parent_scope.module) =>
1167 {
1168 continue;
1169 }
1170 Ok(_) | Err((Undetermined, _)) => {
1171 return true;
1172 }
1173 }
1174 }
1175
1176 false
1177 }
1178
1179 #[instrument(level = "debug", skip(self, all_ribs))]
1181 fn validate_res_from_ribs(
1182 &mut self,
1183 rib_index: usize,
1184 rib_ident: Ident,
1185 mut res: Res,
1186 finalize: Option<Span>,
1187 original_rib_ident_def: Ident,
1188 all_ribs: &[Rib<'ra>],
1189 ) -> Res {
1190 debug!("validate_res_from_ribs({:?})", res);
1191 let ribs = &all_ribs[rib_index + 1..];
1192
1193 if let RibKind::ForwardGenericParamBan(reason) = all_ribs[rib_index].kind {
1196 if let Some(span) = finalize {
1197 let res_error = if rib_ident.name == kw::SelfUpper {
1198 ResolutionError::ForwardDeclaredSelf(reason)
1199 } else {
1200 ResolutionError::ForwardDeclaredGenericParam(rib_ident.name, reason)
1201 };
1202 self.report_error(span, res_error);
1203 }
1204 assert_eq!(res, Res::Err);
1205 return Res::Err;
1206 }
1207
1208 match res {
1209 Res::Local(_) => {
1210 use ResolutionError::*;
1211 let mut res_err = None;
1212
1213 for rib in ribs {
1214 match rib.kind {
1215 RibKind::Normal
1216 | RibKind::Block(..)
1217 | RibKind::FnOrCoroutine
1218 | RibKind::Module(..)
1219 | RibKind::MacroDefinition(..)
1220 | RibKind::ForwardGenericParamBan(_) => {
1221 }
1223 RibKind::Item(..) | RibKind::AssocItem => {
1224 if let Some(span) = finalize {
1228 res_err = Some((span, CannotCaptureDynamicEnvironmentInFnItem));
1233 }
1234 }
1235 RibKind::ConstantItem(_, item) => {
1236 if let Some(span) = finalize {
1238 let (span, resolution_error) = match item {
1239 None if rib_ident.name == kw::SelfLower => {
1240 (span, LowercaseSelf)
1241 }
1242 None => {
1243 let sm = self.tcx.sess.source_map();
1249 let type_span = match sm.span_look_ahead(
1250 original_rib_ident_def.span,
1251 ":",
1252 None,
1253 ) {
1254 None => {
1255 Some(original_rib_ident_def.span.shrink_to_hi())
1256 }
1257 Some(_) => None,
1258 };
1259 (
1260 rib_ident.span,
1261 AttemptToUseNonConstantValueInConstant {
1262 ident: original_rib_ident_def,
1263 suggestion: "const",
1264 current: "let",
1265 type_span,
1266 },
1267 )
1268 }
1269 Some((ident, kind)) => (
1270 span,
1271 AttemptToUseNonConstantValueInConstant {
1272 ident,
1273 suggestion: "let",
1274 current: kind.as_str(),
1275 type_span: None,
1276 },
1277 ),
1278 };
1279 self.report_error(span, resolution_error);
1280 }
1281 return Res::Err;
1282 }
1283 RibKind::ConstParamTy => {
1284 if let Some(span) = finalize {
1285 self.report_error(
1286 span,
1287 ParamInTyOfConstParam { name: rib_ident.name },
1288 );
1289 }
1290 return Res::Err;
1291 }
1292 RibKind::InlineAsmSym => {
1293 if let Some(span) = finalize {
1294 self.report_error(span, InvalidAsmSym);
1295 }
1296 return Res::Err;
1297 }
1298 }
1299 }
1300 if let Some((span, res_err)) = res_err {
1301 self.report_error(span, res_err);
1302 return Res::Err;
1303 }
1304 }
1305 Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {
1306 for rib in ribs {
1307 let (has_generic_params, def_kind) = match rib.kind {
1308 RibKind::Normal
1309 | RibKind::Block(..)
1310 | RibKind::FnOrCoroutine
1311 | RibKind::Module(..)
1312 | RibKind::MacroDefinition(..)
1313 | RibKind::InlineAsmSym
1314 | RibKind::AssocItem
1315 | RibKind::ForwardGenericParamBan(_) => {
1316 continue;
1318 }
1319
1320 RibKind::ConstParamTy => {
1321 if !self.tcx.features().generic_const_parameter_types() {
1322 if let Some(span) = finalize {
1323 self.report_error(
1324 span,
1325 ResolutionError::ParamInTyOfConstParam {
1326 name: rib_ident.name,
1327 },
1328 );
1329 }
1330 return Res::Err;
1331 } else {
1332 continue;
1333 }
1334 }
1335
1336 RibKind::ConstantItem(trivial, _) => {
1337 if let ConstantHasGenerics::No(cause) = trivial {
1338 if let Res::SelfTyAlias {
1343 alias_to: def,
1344 forbid_generic: _,
1345 is_trait_impl,
1346 } = res
1347 {
1348 res = Res::SelfTyAlias {
1349 alias_to: def,
1350 forbid_generic: true,
1351 is_trait_impl,
1352 }
1353 } else {
1354 if let Some(span) = finalize {
1355 let error = match cause {
1356 NoConstantGenericsReason::IsEnumDiscriminant => {
1357 ResolutionError::ParamInEnumDiscriminant {
1358 name: rib_ident.name,
1359 param_kind: ParamKindInEnumDiscriminant::Type,
1360 }
1361 }
1362 NoConstantGenericsReason::NonTrivialConstArg => {
1363 ResolutionError::ParamInNonTrivialAnonConst {
1364 name: rib_ident.name,
1365 param_kind:
1366 ParamKindInNonTrivialAnonConst::Type,
1367 }
1368 }
1369 };
1370 let _: ErrorGuaranteed = self.report_error(span, error);
1371 }
1372
1373 return Res::Err;
1374 }
1375 }
1376
1377 continue;
1378 }
1379
1380 RibKind::Item(has_generic_params, def_kind) => {
1382 (has_generic_params, def_kind)
1383 }
1384 };
1385
1386 if let Some(span) = finalize {
1387 self.report_error(
1388 span,
1389 ResolutionError::GenericParamsFromOuterItem(
1390 res,
1391 has_generic_params,
1392 def_kind,
1393 ),
1394 );
1395 }
1396 return Res::Err;
1397 }
1398 }
1399 Res::Def(DefKind::ConstParam, _) => {
1400 for rib in ribs {
1401 let (has_generic_params, def_kind) = match rib.kind {
1402 RibKind::Normal
1403 | RibKind::Block(..)
1404 | RibKind::FnOrCoroutine
1405 | RibKind::Module(..)
1406 | RibKind::MacroDefinition(..)
1407 | RibKind::InlineAsmSym
1408 | RibKind::AssocItem
1409 | RibKind::ForwardGenericParamBan(_) => continue,
1410
1411 RibKind::ConstParamTy => {
1412 if !self.tcx.features().generic_const_parameter_types() {
1413 if let Some(span) = finalize {
1414 self.report_error(
1415 span,
1416 ResolutionError::ParamInTyOfConstParam {
1417 name: rib_ident.name,
1418 },
1419 );
1420 }
1421 return Res::Err;
1422 } else {
1423 continue;
1424 }
1425 }
1426
1427 RibKind::ConstantItem(trivial, _) => {
1428 if let ConstantHasGenerics::No(cause) = trivial {
1429 if let Some(span) = finalize {
1430 let error = match cause {
1431 NoConstantGenericsReason::IsEnumDiscriminant => {
1432 ResolutionError::ParamInEnumDiscriminant {
1433 name: rib_ident.name,
1434 param_kind: ParamKindInEnumDiscriminant::Const,
1435 }
1436 }
1437 NoConstantGenericsReason::NonTrivialConstArg => {
1438 ResolutionError::ParamInNonTrivialAnonConst {
1439 name: rib_ident.name,
1440 param_kind: ParamKindInNonTrivialAnonConst::Const {
1441 name: rib_ident.name,
1442 },
1443 }
1444 }
1445 };
1446 self.report_error(span, error);
1447 }
1448
1449 return Res::Err;
1450 }
1451
1452 continue;
1453 }
1454
1455 RibKind::Item(has_generic_params, def_kind) => {
1456 (has_generic_params, def_kind)
1457 }
1458 };
1459
1460 if let Some(span) = finalize {
1462 self.report_error(
1463 span,
1464 ResolutionError::GenericParamsFromOuterItem(
1465 res,
1466 has_generic_params,
1467 def_kind,
1468 ),
1469 );
1470 }
1471 return Res::Err;
1472 }
1473 }
1474 _ => {}
1475 }
1476
1477 res
1478 }
1479
1480 #[instrument(level = "debug", skip(self))]
1481 pub(crate) fn maybe_resolve_path<'r>(
1482 self: CmResolver<'r, 'ra, 'tcx>,
1483 path: &[Segment],
1484 opt_ns: Option<Namespace>, parent_scope: &ParentScope<'ra>,
1486 ignore_import: Option<Import<'ra>>,
1487 ) -> PathResult<'ra> {
1488 self.resolve_path_with_ribs(
1489 path,
1490 opt_ns,
1491 parent_scope,
1492 None,
1493 None,
1494 None,
1495 None,
1496 ignore_import,
1497 )
1498 }
1499 #[instrument(level = "debug", skip(self))]
1500 pub(crate) fn resolve_path<'r>(
1501 self: CmResolver<'r, 'ra, 'tcx>,
1502 path: &[Segment],
1503 opt_ns: Option<Namespace>, parent_scope: &ParentScope<'ra>,
1505 finalize: Option<Finalize>,
1506 ignore_binding: Option<NameBinding<'ra>>,
1507 ignore_import: Option<Import<'ra>>,
1508 ) -> PathResult<'ra> {
1509 self.resolve_path_with_ribs(
1510 path,
1511 opt_ns,
1512 parent_scope,
1513 None,
1514 finalize,
1515 None,
1516 ignore_binding,
1517 ignore_import,
1518 )
1519 }
1520
1521 pub(crate) fn resolve_path_with_ribs<'r>(
1522 mut self: CmResolver<'r, 'ra, 'tcx>,
1523 path: &[Segment],
1524 opt_ns: Option<Namespace>, parent_scope: &ParentScope<'ra>,
1526 source: Option<PathSource<'_, '_, '_>>,
1527 finalize: Option<Finalize>,
1528 ribs: Option<&PerNS<Vec<Rib<'ra>>>>,
1529 ignore_binding: Option<NameBinding<'ra>>,
1530 ignore_import: Option<Import<'ra>>,
1531 ) -> PathResult<'ra> {
1532 let mut module = None;
1533 let mut module_had_parse_errors = false;
1534 let mut allow_super = true;
1535 let mut second_binding = None;
1536
1537 let privacy_errors_len = self.privacy_errors.len();
1539 fn record_segment_res<'r, 'ra, 'tcx>(
1540 mut this: CmResolver<'r, 'ra, 'tcx>,
1541 finalize: Option<Finalize>,
1542 res: Res,
1543 id: Option<NodeId>,
1544 ) {
1545 if finalize.is_some()
1546 && let Some(id) = id
1547 && !this.partial_res_map.contains_key(&id)
1548 {
1549 assert!(id != ast::DUMMY_NODE_ID, "Trying to resolve dummy id");
1550 this.get_mut().record_partial_res(id, PartialRes::new(res));
1551 }
1552 }
1553
1554 for (segment_idx, &Segment { ident, id, .. }) in path.iter().enumerate() {
1555 debug!("resolve_path ident {} {:?} {:?}", segment_idx, ident, id);
1556
1557 let is_last = segment_idx + 1 == path.len();
1558 let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };
1559 let name = ident.name;
1560
1561 allow_super &= ns == TypeNS && (name == kw::SelfLower || name == kw::Super);
1562
1563 if ns == TypeNS {
1564 if allow_super && name == kw::Super {
1565 let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();
1566 let self_module = match segment_idx {
1567 0 => Some(self.resolve_self(&mut ctxt, parent_scope.module)),
1568 _ => match module {
1569 Some(ModuleOrUniformRoot::Module(module)) => Some(module),
1570 _ => None,
1571 },
1572 };
1573 if let Some(self_module) = self_module
1574 && let Some(parent) = self_module.parent
1575 {
1576 module =
1577 Some(ModuleOrUniformRoot::Module(self.resolve_self(&mut ctxt, parent)));
1578 continue;
1579 }
1580 return PathResult::failed(
1581 ident,
1582 false,
1583 finalize.is_some(),
1584 module_had_parse_errors,
1585 module,
1586 || ("there are too many leading `super` keywords".to_string(), None),
1587 );
1588 }
1589 if segment_idx == 0 {
1590 if name == kw::SelfLower {
1591 let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();
1592 let self_mod = self.resolve_self(&mut ctxt, parent_scope.module);
1593 if let Some(res) = self_mod.res() {
1594 record_segment_res(self.reborrow(), finalize, res, id);
1595 }
1596 module = Some(ModuleOrUniformRoot::Module(self_mod));
1597 continue;
1598 }
1599 if name == kw::PathRoot && ident.span.at_least_rust_2018() {
1600 module = Some(ModuleOrUniformRoot::ExternPrelude);
1601 continue;
1602 }
1603 if name == kw::PathRoot
1604 && ident.span.is_rust_2015()
1605 && self.tcx.sess.at_least_rust_2018()
1606 {
1607 let crate_root = self.resolve_crate_root(ident);
1609 module = Some(ModuleOrUniformRoot::ModuleAndExternPrelude(crate_root));
1610 continue;
1611 }
1612 if name == kw::PathRoot || name == kw::Crate || name == kw::DollarCrate {
1613 let crate_root = self.resolve_crate_root(ident);
1615 if let Some(res) = crate_root.res() {
1616 record_segment_res(self.reborrow(), finalize, res, id);
1617 }
1618 module = Some(ModuleOrUniformRoot::Module(crate_root));
1619 continue;
1620 }
1621 }
1622 }
1623
1624 if ident.is_path_segment_keyword() && segment_idx != 0 {
1626 return PathResult::failed(
1627 ident,
1628 false,
1629 finalize.is_some(),
1630 module_had_parse_errors,
1631 module,
1632 || {
1633 let name_str = if name == kw::PathRoot {
1634 "crate root".to_string()
1635 } else {
1636 format!("`{name}`")
1637 };
1638 let label = if segment_idx == 1 && path[0].ident.name == kw::PathRoot {
1639 format!("global paths cannot start with {name_str}")
1640 } else {
1641 format!("{name_str} in paths can only be used in start position")
1642 };
1643 (label, None)
1644 },
1645 );
1646 }
1647
1648 let binding = if let Some(module) = module {
1649 self.reborrow()
1650 .resolve_ident_in_module(
1651 module,
1652 ident,
1653 ns,
1654 parent_scope,
1655 finalize,
1656 ignore_binding,
1657 ignore_import,
1658 )
1659 .map_err(|(determinacy, _)| determinacy)
1660 } else if let Some(ribs) = ribs
1661 && let Some(TypeNS | ValueNS) = opt_ns
1662 {
1663 assert!(ignore_import.is_none());
1664 match self.get_mut().resolve_ident_in_lexical_scope(
1665 ident,
1666 ns,
1667 parent_scope,
1668 finalize,
1669 &ribs[ns],
1670 ignore_binding,
1671 ) {
1672 Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
1674 Some(LexicalScopeBinding::Res(res)) => {
1676 record_segment_res(self.reborrow(), finalize, res, id);
1677 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1678 res,
1679 path.len() - 1,
1680 ));
1681 }
1682 _ => Err(Determinacy::determined(finalize.is_some())),
1683 }
1684 } else {
1685 self.reborrow().resolve_ident_in_scope_set(
1686 ident,
1687 ScopeSet::All(ns),
1688 parent_scope,
1689 finalize,
1690 finalize.is_some(),
1691 ignore_binding,
1692 ignore_import,
1693 )
1694 };
1695
1696 match binding {
1697 Ok(binding) => {
1698 if segment_idx == 1 {
1699 second_binding = Some(binding);
1700 }
1701 let res = binding.res();
1702
1703 if finalize.is_some() {
1707 for error in &mut self.get_mut().privacy_errors[privacy_errors_len..] {
1708 error.outermost_res = Some((res, ident));
1709 error.source = match source {
1710 Some(PathSource::Struct(Some(expr)))
1711 | Some(PathSource::Expr(Some(expr))) => Some(expr.clone()),
1712 _ => None,
1713 };
1714 }
1715 }
1716
1717 let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(res);
1718 if let Some(def_id) = binding.res().module_like_def_id() {
1719 if self.mods_with_parse_errors.contains(&def_id) {
1720 module_had_parse_errors = true;
1721 }
1722 module = Some(ModuleOrUniformRoot::Module(self.expect_module(def_id)));
1723 record_segment_res(self.reborrow(), finalize, res, id);
1724 } else if res == Res::ToolMod && !is_last && opt_ns.is_some() {
1725 if binding.is_import() {
1726 self.dcx().emit_err(errors::ToolModuleImported {
1727 span: ident.span,
1728 import: binding.span,
1729 });
1730 }
1731 let res = Res::NonMacroAttr(NonMacroAttrKind::Tool);
1732 return PathResult::NonModule(PartialRes::new(res));
1733 } else if res == Res::Err {
1734 return PathResult::NonModule(PartialRes::new(Res::Err));
1735 } else if opt_ns.is_some() && (is_last || maybe_assoc) {
1736 if let Some(finalize) = finalize {
1737 self.get_mut().lint_if_path_starts_with_module(
1738 finalize,
1739 path,
1740 second_binding,
1741 );
1742 }
1743 record_segment_res(self.reborrow(), finalize, res, id);
1744 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1745 res,
1746 path.len() - segment_idx - 1,
1747 ));
1748 } else {
1749 return PathResult::failed(
1750 ident,
1751 is_last,
1752 finalize.is_some(),
1753 module_had_parse_errors,
1754 module,
1755 || {
1756 let label = format!(
1757 "`{ident}` is {} {}, not a module",
1758 res.article(),
1759 res.descr()
1760 );
1761 (label, None)
1762 },
1763 );
1764 }
1765 }
1766 Err(Undetermined) => return PathResult::Indeterminate,
1767 Err(Determined) => {
1768 if let Some(ModuleOrUniformRoot::Module(module)) = module
1769 && opt_ns.is_some()
1770 && !module.is_normal()
1771 {
1772 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1773 module.res().unwrap(),
1774 path.len() - segment_idx,
1775 ));
1776 }
1777
1778 let mut this = self.reborrow();
1779 return PathResult::failed(
1780 ident,
1781 is_last,
1782 finalize.is_some(),
1783 module_had_parse_errors,
1784 module,
1785 || {
1786 this.get_mut().report_path_resolution_error(
1787 path,
1788 opt_ns,
1789 parent_scope,
1790 ribs,
1791 ignore_binding,
1792 ignore_import,
1793 module,
1794 segment_idx,
1795 ident,
1796 )
1797 },
1798 );
1799 }
1800 }
1801 }
1802
1803 if let Some(finalize) = finalize {
1804 self.get_mut().lint_if_path_starts_with_module(finalize, path, second_binding);
1805 }
1806
1807 PathResult::Module(match module {
1808 Some(module) => module,
1809 None if path.is_empty() => ModuleOrUniformRoot::CurrentScope,
1810 _ => bug!("resolve_path: non-empty path `{:?}` has no module", path),
1811 })
1812 }
1813}