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