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