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 for (i, rib) in ribs.iter().enumerate().rev() {
322 debug!("walk rib\n{:?}", rib.bindings);
323 let rib_ident = if rib.kind.contains_params() { normalized_ident } else { ident };
326 if let Some((original_rib_ident_def, res)) = rib.bindings.get_key_value(&rib_ident) {
327 return Some(LexicalScopeBinding::Res(self.validate_res_from_ribs(
329 i,
330 rib_ident,
331 *res,
332 finalize.map(|finalize| finalize.path_span),
333 *original_rib_ident_def,
334 ribs,
335 )));
336 } else if let RibKind::Block(Some(module)) = rib.kind
337 && let Ok(binding) = self.cm().resolve_ident_in_module_unadjusted(
338 ModuleOrUniformRoot::Module(module),
339 ident,
340 ns,
341 parent_scope,
342 Shadowing::Unrestricted,
343 finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }),
344 ignore_binding,
345 None,
346 )
347 {
348 return Some(LexicalScopeBinding::Item(binding));
350 } else if let RibKind::Module(module) = rib.kind {
351 return self
353 .cm()
354 .early_resolve_ident_in_lexical_scope(
355 orig_ident,
356 ScopeSet::Late(ns, module, finalize.map(|finalize| finalize.node_id)),
357 parent_scope,
358 finalize,
359 finalize.is_some(),
360 ignore_binding,
361 None,
362 )
363 .ok()
364 .map(LexicalScopeBinding::Item);
365 }
366
367 if let RibKind::MacroDefinition(def) = rib.kind
368 && def == self.macro_def(ident.span.ctxt())
369 {
370 ident.span.remove_mark();
373 }
374 }
375
376 unreachable!()
377 }
378
379 #[instrument(level = "debug", skip(self))]
385 pub(crate) fn early_resolve_ident_in_lexical_scope<'r>(
386 self: CmResolver<'r, 'ra, 'tcx>,
387 orig_ident: Ident,
388 scope_set: ScopeSet<'ra>,
389 parent_scope: &ParentScope<'ra>,
390 finalize: Option<Finalize>,
391 force: bool,
392 ignore_binding: Option<NameBinding<'ra>>,
393 ignore_import: Option<Import<'ra>>,
394 ) -> Result<NameBinding<'ra>, Determinacy> {
395 bitflags::bitflags! {
396 #[derive(Clone, Copy)]
397 struct Flags: u8 {
398 const MACRO_RULES = 1 << 0;
399 const MODULE = 1 << 1;
400 const MISC_SUGGEST_CRATE = 1 << 2;
401 const MISC_SUGGEST_SELF = 1 << 3;
402 const MISC_FROM_PRELUDE = 1 << 4;
403 }
404 }
405
406 assert!(force || finalize.is_none()); if orig_ident.is_path_segment_keyword() {
410 return Err(Determinacy::Determined);
411 }
412
413 let (ns, macro_kind) = match scope_set {
414 ScopeSet::All(ns)
415 | ScopeSet::ModuleAndExternPrelude(ns, _)
416 | ScopeSet::Late(ns, ..) => (ns, None),
417 ScopeSet::ExternPrelude => (TypeNS, None),
418 ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
419 };
420
421 let mut innermost_result: Option<(NameBinding<'_>, Flags)> = None;
433 let mut determinacy = Determinacy::Determined;
434 macro finalize_scope() {
436 if innermost_result.is_none() { finalize } else { None }
437 }
438
439 let break_result = self.visit_scopes(
441 scope_set,
442 parent_scope,
443 orig_ident.span.ctxt(),
444 |this, scope, use_prelude, ctxt| {
445 let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt));
446 let result = match scope {
447 Scope::DeriveHelpers(expn_id) => {
448 if let Some(binding) = this.helper_attrs.get(&expn_id).and_then(|attrs| {
449 attrs.iter().rfind(|(i, _)| ident == *i).map(|(_, binding)| *binding)
450 }) {
451 Ok((binding, Flags::empty()))
452 } else {
453 Err(Determinacy::Determined)
454 }
455 }
456 Scope::DeriveHelpersCompat => {
457 let mut result = Err(Determinacy::Determined);
458 for derive in parent_scope.derives {
459 let parent_scope = &ParentScope { derives: &[], ..*parent_scope };
460 match this.reborrow().resolve_macro_path(
461 derive,
462 MacroKind::Derive,
463 parent_scope,
464 true,
465 force,
466 ignore_import,
467 None,
468 ) {
469 Ok((Some(ext), _)) => {
470 if ext.helper_attrs.contains(&ident.name) {
471 let binding = this.arenas.new_pub_res_binding(
472 Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat),
473 derive.span,
474 LocalExpnId::ROOT,
475 );
476 result = Ok((binding, Flags::empty()));
477 break;
478 }
479 }
480 Ok(_) | Err(Determinacy::Determined) => {}
481 Err(Determinacy::Undetermined) => {
482 result = Err(Determinacy::Undetermined)
483 }
484 }
485 }
486 result
487 }
488 Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() {
489 MacroRulesScope::Binding(macro_rules_binding)
490 if ident == macro_rules_binding.ident =>
491 {
492 Ok((macro_rules_binding.binding, Flags::MACRO_RULES))
493 }
494 MacroRulesScope::Invocation(_) => Err(Determinacy::Undetermined),
495 _ => Err(Determinacy::Determined),
496 },
497 Scope::Module(module, derive_fallback_lint_id) => {
498 let (adjusted_parent_scope, adjusted_finalize) =
500 if matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..)) {
501 (parent_scope, finalize)
502 } else {
503 (
504 &ParentScope { module, ..*parent_scope },
505 finalize.map(|f| Finalize { used: Used::Scope, ..f }),
506 )
507 };
508 let binding = this.reborrow().resolve_ident_in_module_unadjusted(
509 ModuleOrUniformRoot::Module(module),
510 ident,
511 ns,
512 adjusted_parent_scope,
513 if matches!(scope_set, ScopeSet::Late(..)) {
514 Shadowing::Unrestricted
515 } else {
516 Shadowing::Restricted
517 },
518 adjusted_finalize,
519 ignore_binding,
520 ignore_import,
521 );
522 match binding {
523 Ok(binding) => {
524 if let Some(lint_id) = derive_fallback_lint_id {
525 this.get_mut().lint_buffer.buffer_lint(
526 PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
527 lint_id,
528 orig_ident.span,
529 BuiltinLintDiag::ProcMacroDeriveResolutionFallback {
530 span: orig_ident.span,
531 ns,
532 ident,
533 },
534 );
535 }
536 let misc_flags = if module == this.graph_root {
537 Flags::MISC_SUGGEST_CRATE
538 } else if module.is_normal() {
539 Flags::MISC_SUGGEST_SELF
540 } else {
541 Flags::empty()
542 };
543 Ok((binding, Flags::MODULE | misc_flags))
544 }
545 Err((Determinacy::Undetermined, Weak::No)) => {
546 return Some(Err(Determinacy::determined(force)));
547 }
548 Err((Determinacy::Undetermined, Weak::Yes)) => {
549 Err(Determinacy::Undetermined)
550 }
551 Err((Determinacy::Determined, _)) => Err(Determinacy::Determined),
552 }
553 }
554 Scope::MacroUsePrelude => {
555 match this.macro_use_prelude.get(&ident.name).cloned() {
556 Some(binding) => Ok((binding, Flags::MISC_FROM_PRELUDE)),
557 None => Err(Determinacy::determined(
558 this.graph_root.unexpanded_invocations.borrow().is_empty(),
559 )),
560 }
561 }
562 Scope::BuiltinAttrs => match this.builtin_attrs_bindings.get(&ident.name) {
563 Some(binding) => Ok((*binding, Flags::empty())),
564 None => Err(Determinacy::Determined),
565 },
566 Scope::ExternPreludeItems => {
567 match this.reborrow().extern_prelude_get_item(ident, finalize.is_some()) {
569 Some(binding) => Ok((binding, Flags::empty())),
570 None => Err(Determinacy::determined(
571 this.graph_root.unexpanded_invocations.borrow().is_empty(),
572 )),
573 }
574 }
575 Scope::ExternPreludeFlags => {
576 match this.extern_prelude_get_flag(ident, finalize_scope!().is_some()) {
577 Some(binding) => Ok((binding, Flags::empty())),
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 finalize.is_none() || matches!(scope_set, ScopeSet::Late(..)) {
647 return Some(Ok(binding));
648 }
649
650 if let Some((innermost_binding, innermost_flags)) = innermost_result {
651 let (res, innermost_res) = (binding.res(), innermost_binding.res());
653 if res != innermost_res {
654 let is_builtin = |res| {
655 matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Builtin(..)))
656 };
657 let derive_helper =
658 Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
659 let derive_helper_compat =
660 Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat);
661
662 let ambiguity_error_kind = if is_builtin(innermost_res)
663 || is_builtin(res)
664 {
665 Some(AmbiguityKind::BuiltinAttr)
666 } else if innermost_res == derive_helper_compat
667 || res == derive_helper_compat && innermost_res != derive_helper
668 {
669 Some(AmbiguityKind::DeriveHelper)
670 } else if innermost_flags.contains(Flags::MACRO_RULES)
671 && flags.contains(Flags::MODULE)
672 && !this.disambiguate_macro_rules_vs_modularized(
673 innermost_binding,
674 binding,
675 )
676 || flags.contains(Flags::MACRO_RULES)
677 && innermost_flags.contains(Flags::MODULE)
678 && !this.disambiguate_macro_rules_vs_modularized(
679 binding,
680 innermost_binding,
681 )
682 {
683 Some(AmbiguityKind::MacroRulesVsModularized)
684 } else if innermost_binding.is_glob_import() {
685 Some(AmbiguityKind::GlobVsOuter)
686 } else if innermost_binding
687 .may_appear_after(parent_scope.expansion, binding)
688 {
689 Some(AmbiguityKind::MoreExpandedVsOuter)
690 } else {
691 None
692 };
693 if let Some(kind) = ambiguity_error_kind {
694 let misc = |f: Flags| {
695 if f.contains(Flags::MISC_SUGGEST_CRATE) {
696 AmbiguityErrorMisc::SuggestCrate
697 } else if f.contains(Flags::MISC_SUGGEST_SELF) {
698 AmbiguityErrorMisc::SuggestSelf
699 } else if f.contains(Flags::MISC_FROM_PRELUDE) {
700 AmbiguityErrorMisc::FromPrelude
701 } else {
702 AmbiguityErrorMisc::None
703 }
704 };
705 this.get_mut().ambiguity_errors.push(AmbiguityError {
706 kind,
707 ident: orig_ident,
708 b1: innermost_binding,
709 b2: binding,
710 warning: false,
711 misc1: misc(innermost_flags),
712 misc2: misc(flags),
713 });
714 return Some(Ok(innermost_binding));
715 }
716 }
717 } else {
718 innermost_result = Some((binding, flags));
720 }
721 }
722 Err(Determinacy::Determined) => {}
723 Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined,
724 }
725
726 None
727 },
728 );
729
730 if let Some(break_result) = break_result {
731 return break_result;
732 }
733
734 if let Some((binding, _)) = innermost_result {
736 return Ok(binding);
737 }
738
739 Err(Determinacy::determined(determinacy == Determinacy::Determined || force))
740 }
741
742 #[instrument(level = "debug", skip(self))]
743 pub(crate) fn maybe_resolve_ident_in_module<'r>(
744 self: CmResolver<'r, 'ra, 'tcx>,
745 module: ModuleOrUniformRoot<'ra>,
746 ident: Ident,
747 ns: Namespace,
748 parent_scope: &ParentScope<'ra>,
749 ignore_import: Option<Import<'ra>>,
750 ) -> Result<NameBinding<'ra>, Determinacy> {
751 self.resolve_ident_in_module(module, ident, ns, parent_scope, None, None, ignore_import)
752 .map_err(|(determinacy, _)| determinacy)
753 }
754
755 #[instrument(level = "debug", skip(self))]
756 pub(crate) fn resolve_ident_in_module<'r>(
757 self: CmResolver<'r, 'ra, 'tcx>,
758 module: ModuleOrUniformRoot<'ra>,
759 mut ident: Ident,
760 ns: Namespace,
761 parent_scope: &ParentScope<'ra>,
762 finalize: Option<Finalize>,
763 ignore_binding: Option<NameBinding<'ra>>,
764 ignore_import: Option<Import<'ra>>,
765 ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
766 let tmp_parent_scope;
767 let mut adjusted_parent_scope = parent_scope;
768 match module {
769 ModuleOrUniformRoot::Module(m) => {
770 if let Some(def) = ident.span.normalize_to_macros_2_0_and_adjust(m.expansion) {
771 tmp_parent_scope =
772 ParentScope { module: self.expn_def_scope(def), ..*parent_scope };
773 adjusted_parent_scope = &tmp_parent_scope;
774 }
775 }
776 ModuleOrUniformRoot::ExternPrelude => {
777 ident.span.normalize_to_macros_2_0_and_adjust(ExpnId::root());
778 }
779 ModuleOrUniformRoot::ModuleAndExternPrelude(..) | ModuleOrUniformRoot::CurrentScope => {
780 }
782 }
783 self.resolve_ident_in_module_unadjusted(
784 module,
785 ident,
786 ns,
787 adjusted_parent_scope,
788 Shadowing::Unrestricted,
789 finalize,
790 ignore_binding,
791 ignore_import,
792 )
793 }
794 #[instrument(level = "debug", skip(self))]
797 fn resolve_ident_in_module_unadjusted<'r>(
798 mut self: CmResolver<'r, 'ra, 'tcx>,
799 module: ModuleOrUniformRoot<'ra>,
800 ident: Ident,
801 ns: Namespace,
802 parent_scope: &ParentScope<'ra>,
803 shadowing: Shadowing,
804 finalize: Option<Finalize>,
805 ignore_binding: Option<NameBinding<'ra>>,
808 ignore_import: Option<Import<'ra>>,
809 ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
810 let module = match module {
811 ModuleOrUniformRoot::Module(module) => module,
812 ModuleOrUniformRoot::ModuleAndExternPrelude(module) => {
813 assert_eq!(shadowing, Shadowing::Unrestricted);
814 let binding = self.early_resolve_ident_in_lexical_scope(
815 ident,
816 ScopeSet::ModuleAndExternPrelude(ns, module),
817 parent_scope,
818 finalize,
819 finalize.is_some(),
820 ignore_binding,
821 ignore_import,
822 );
823 return binding.map_err(|determinacy| (determinacy, Weak::No));
824 }
825 ModuleOrUniformRoot::ExternPrelude => {
826 assert_eq!(shadowing, Shadowing::Unrestricted);
827 return if ns != TypeNS {
828 Err((Determined, Weak::No))
829 } else {
830 let binding = self.early_resolve_ident_in_lexical_scope(
831 ident,
832 ScopeSet::ExternPrelude,
833 parent_scope,
834 finalize,
835 finalize.is_some(),
836 ignore_binding,
837 ignore_import,
838 );
839 return binding.map_err(|determinacy| (determinacy, Weak::No));
840 };
841 }
842 ModuleOrUniformRoot::CurrentScope => {
843 assert_eq!(shadowing, Shadowing::Unrestricted);
844 if ns == TypeNS {
845 if ident.name == kw::Crate || ident.name == kw::DollarCrate {
846 let module = self.resolve_crate_root(ident);
847 return Ok(module.self_binding.unwrap());
848 } else if ident.name == kw::Super || ident.name == kw::SelfLower {
849 }
853 }
854
855 let binding = self.early_resolve_ident_in_lexical_scope(
856 ident,
857 ScopeSet::All(ns),
858 parent_scope,
859 finalize,
860 finalize.is_some(),
861 ignore_binding,
862 ignore_import,
863 );
864 return binding.map_err(|determinacy| (determinacy, Weak::No));
865 }
866 };
867
868 let key = BindingKey::new(ident, ns);
869 let resolution = &*self
873 .resolution_or_default(module, key)
874 .try_borrow_mut()
875 .map_err(|_| (Determined, Weak::No))?;
876
877 let binding = [resolution.non_glob_binding, resolution.glob_binding]
882 .into_iter()
883 .find_map(|binding| if binding == ignore_binding { None } else { binding });
884
885 if let Some(finalize) = finalize {
886 return self.get_mut().finalize_module_binding(
887 ident,
888 binding,
889 if resolution.non_glob_binding.is_some() { resolution.glob_binding } else { None },
890 parent_scope,
891 finalize,
892 shadowing,
893 );
894 }
895
896 let check_usable = |this: CmResolver<'r, 'ra, 'tcx>, binding: NameBinding<'ra>| {
897 let usable = this.is_accessible_from(binding.vis, parent_scope.module);
898 if usable { Ok(binding) } else { Err((Determined, Weak::No)) }
899 };
900
901 if let Some(binding) = binding
903 && !binding.is_glob_import()
904 {
905 return check_usable(self, binding);
906 }
907
908 if self.reborrow().single_import_can_define_name(
913 &resolution,
914 binding,
915 ns,
916 ignore_import,
917 ignore_binding,
918 parent_scope,
919 ) {
920 return Err((Undetermined, Weak::No));
921 }
922
923 if let Some(binding) = binding {
936 if binding.determined() || ns == MacroNS || shadowing == Shadowing::Restricted {
937 return check_usable(self, binding);
938 } else {
939 return Err((Undetermined, Weak::No));
940 }
941 }
942
943 if !module.unexpanded_invocations.borrow().is_empty() {
954 return Err((Undetermined, Weak::Yes));
955 }
956
957 for glob_import in module.globs.borrow().iter() {
960 if ignore_import == Some(*glob_import) {
961 continue;
962 }
963 if !self.is_accessible_from(glob_import.vis, parent_scope.module) {
964 continue;
965 }
966 let module = match glob_import.imported_module.get() {
967 Some(ModuleOrUniformRoot::Module(module)) => module,
968 Some(_) => continue,
969 None => return Err((Undetermined, Weak::Yes)),
970 };
971 let tmp_parent_scope;
972 let (mut adjusted_parent_scope, mut ident) =
973 (parent_scope, ident.normalize_to_macros_2_0());
974 match ident.span.glob_adjust(module.expansion, glob_import.span) {
975 Some(Some(def)) => {
976 tmp_parent_scope =
977 ParentScope { module: self.expn_def_scope(def), ..*parent_scope };
978 adjusted_parent_scope = &tmp_parent_scope;
979 }
980 Some(None) => {}
981 None => continue,
982 };
983 let result = self.reborrow().resolve_ident_in_module_unadjusted(
984 ModuleOrUniformRoot::Module(module),
985 ident,
986 ns,
987 adjusted_parent_scope,
988 Shadowing::Unrestricted,
989 None,
990 ignore_binding,
991 ignore_import,
992 );
993
994 match result {
995 Err((Determined, _)) => continue,
996 Ok(binding)
997 if !self.is_accessible_from(binding.vis, glob_import.parent_scope.module) =>
998 {
999 continue;
1000 }
1001 Ok(_) | Err((Undetermined, _)) => return Err((Undetermined, Weak::Yes)),
1002 }
1003 }
1004
1005 Err((Determined, Weak::No))
1007 }
1008
1009 fn finalize_module_binding(
1010 &mut self,
1011 ident: Ident,
1012 binding: Option<NameBinding<'ra>>,
1013 shadowed_glob: Option<NameBinding<'ra>>,
1014 parent_scope: &ParentScope<'ra>,
1015 finalize: Finalize,
1016 shadowing: Shadowing,
1017 ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
1018 let Finalize { path_span, report_private, used, root_span, .. } = finalize;
1019
1020 let Some(binding) = binding else {
1021 return Err((Determined, Weak::No));
1022 };
1023
1024 if !self.is_accessible_from(binding.vis, parent_scope.module) {
1025 if report_private {
1026 self.privacy_errors.push(PrivacyError {
1027 ident,
1028 binding,
1029 dedup_span: path_span,
1030 outermost_res: None,
1031 source: None,
1032 parent_scope: *parent_scope,
1033 single_nested: path_span != root_span,
1034 });
1035 } else {
1036 return Err((Determined, Weak::No));
1037 }
1038 }
1039
1040 if let Some(shadowed_glob) = shadowed_glob
1042 && shadowing == Shadowing::Restricted
1043 && binding.expansion != LocalExpnId::ROOT
1044 && binding.res() != shadowed_glob.res()
1045 {
1046 self.ambiguity_errors.push(AmbiguityError {
1047 kind: AmbiguityKind::GlobVsExpanded,
1048 ident,
1049 b1: binding,
1050 b2: shadowed_glob,
1051 warning: false,
1052 misc1: AmbiguityErrorMisc::None,
1053 misc2: AmbiguityErrorMisc::None,
1054 });
1055 }
1056
1057 if shadowing == Shadowing::Unrestricted
1058 && binding.expansion != LocalExpnId::ROOT
1059 && let NameBindingKind::Import { import, .. } = binding.kind
1060 && matches!(import.kind, ImportKind::MacroExport)
1061 {
1062 self.macro_expanded_macro_export_errors.insert((path_span, binding.span));
1063 }
1064
1065 self.record_use(ident, binding, used);
1066 return Ok(binding);
1067 }
1068
1069 fn single_import_can_define_name<'r>(
1072 mut self: CmResolver<'r, 'ra, 'tcx>,
1073 resolution: &NameResolution<'ra>,
1074 binding: Option<NameBinding<'ra>>,
1075 ns: Namespace,
1076 ignore_import: Option<Import<'ra>>,
1077 ignore_binding: Option<NameBinding<'ra>>,
1078 parent_scope: &ParentScope<'ra>,
1079 ) -> bool {
1080 for single_import in &resolution.single_imports {
1081 if ignore_import == Some(*single_import) {
1082 continue;
1083 }
1084 if !self.is_accessible_from(single_import.vis, parent_scope.module) {
1085 continue;
1086 }
1087 if let Some(ignored) = ignore_binding
1088 && let NameBindingKind::Import { import, .. } = ignored.kind
1089 && import == *single_import
1090 {
1091 continue;
1092 }
1093
1094 let Some(module) = single_import.imported_module.get() else {
1095 return true;
1096 };
1097 let ImportKind::Single { source, target, bindings, .. } = &single_import.kind else {
1098 unreachable!();
1099 };
1100 if source != target {
1101 if bindings.iter().all(|binding| binding.get().binding().is_none()) {
1102 return true;
1103 } else if bindings[ns].get().binding().is_none() && binding.is_some() {
1104 return true;
1105 }
1106 }
1107
1108 match self.reborrow().resolve_ident_in_module(
1109 module,
1110 *source,
1111 ns,
1112 &single_import.parent_scope,
1113 None,
1114 ignore_binding,
1115 ignore_import,
1116 ) {
1117 Err((Determined, _)) => continue,
1118 Ok(binding)
1119 if !self.is_accessible_from(binding.vis, single_import.parent_scope.module) =>
1120 {
1121 continue;
1122 }
1123 Ok(_) | Err((Undetermined, _)) => {
1124 return true;
1125 }
1126 }
1127 }
1128
1129 false
1130 }
1131
1132 #[instrument(level = "debug", skip(self, all_ribs))]
1134 fn validate_res_from_ribs(
1135 &mut self,
1136 rib_index: usize,
1137 rib_ident: Ident,
1138 mut res: Res,
1139 finalize: Option<Span>,
1140 original_rib_ident_def: Ident,
1141 all_ribs: &[Rib<'ra>],
1142 ) -> Res {
1143 debug!("validate_res_from_ribs({:?})", res);
1144 let ribs = &all_ribs[rib_index + 1..];
1145
1146 if let RibKind::ForwardGenericParamBan(reason) = all_ribs[rib_index].kind {
1149 if let Some(span) = finalize {
1150 let res_error = if rib_ident.name == kw::SelfUpper {
1151 ResolutionError::ForwardDeclaredSelf(reason)
1152 } else {
1153 ResolutionError::ForwardDeclaredGenericParam(rib_ident.name, reason)
1154 };
1155 self.report_error(span, res_error);
1156 }
1157 assert_eq!(res, Res::Err);
1158 return Res::Err;
1159 }
1160
1161 match res {
1162 Res::Local(_) => {
1163 use ResolutionError::*;
1164 let mut res_err = None;
1165
1166 for rib in ribs {
1167 match rib.kind {
1168 RibKind::Normal
1169 | RibKind::Block(..)
1170 | RibKind::FnOrCoroutine
1171 | RibKind::Module(..)
1172 | RibKind::MacroDefinition(..)
1173 | RibKind::ForwardGenericParamBan(_) => {
1174 }
1176 RibKind::Item(..) | RibKind::AssocItem => {
1177 if let Some(span) = finalize {
1181 res_err = Some((span, CannotCaptureDynamicEnvironmentInFnItem));
1186 }
1187 }
1188 RibKind::ConstantItem(_, item) => {
1189 if let Some(span) = finalize {
1191 let (span, resolution_error) = match item {
1192 None if rib_ident.name == kw::SelfLower => {
1193 (span, LowercaseSelf)
1194 }
1195 None => {
1196 let sm = self.tcx.sess.source_map();
1202 let type_span = match sm.span_look_ahead(
1203 original_rib_ident_def.span,
1204 ":",
1205 None,
1206 ) {
1207 None => {
1208 Some(original_rib_ident_def.span.shrink_to_hi())
1209 }
1210 Some(_) => None,
1211 };
1212 (
1213 rib_ident.span,
1214 AttemptToUseNonConstantValueInConstant {
1215 ident: original_rib_ident_def,
1216 suggestion: "const",
1217 current: "let",
1218 type_span,
1219 },
1220 )
1221 }
1222 Some((ident, kind)) => (
1223 span,
1224 AttemptToUseNonConstantValueInConstant {
1225 ident,
1226 suggestion: "let",
1227 current: kind.as_str(),
1228 type_span: None,
1229 },
1230 ),
1231 };
1232 self.report_error(span, resolution_error);
1233 }
1234 return Res::Err;
1235 }
1236 RibKind::ConstParamTy => {
1237 if let Some(span) = finalize {
1238 self.report_error(
1239 span,
1240 ParamInTyOfConstParam { name: rib_ident.name },
1241 );
1242 }
1243 return Res::Err;
1244 }
1245 RibKind::InlineAsmSym => {
1246 if let Some(span) = finalize {
1247 self.report_error(span, InvalidAsmSym);
1248 }
1249 return Res::Err;
1250 }
1251 }
1252 }
1253 if let Some((span, res_err)) = res_err {
1254 self.report_error(span, res_err);
1255 return Res::Err;
1256 }
1257 }
1258 Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {
1259 for rib in ribs {
1260 let (has_generic_params, def_kind) = match rib.kind {
1261 RibKind::Normal
1262 | RibKind::Block(..)
1263 | RibKind::FnOrCoroutine
1264 | RibKind::Module(..)
1265 | RibKind::MacroDefinition(..)
1266 | RibKind::InlineAsmSym
1267 | RibKind::AssocItem
1268 | RibKind::ForwardGenericParamBan(_) => {
1269 continue;
1271 }
1272
1273 RibKind::ConstParamTy => {
1274 if !self.tcx.features().generic_const_parameter_types() {
1275 if let Some(span) = finalize {
1276 self.report_error(
1277 span,
1278 ResolutionError::ParamInTyOfConstParam {
1279 name: rib_ident.name,
1280 },
1281 );
1282 }
1283 return Res::Err;
1284 } else {
1285 continue;
1286 }
1287 }
1288
1289 RibKind::ConstantItem(trivial, _) => {
1290 if let ConstantHasGenerics::No(cause) = trivial {
1291 if let Res::SelfTyAlias {
1296 alias_to: def,
1297 forbid_generic: _,
1298 is_trait_impl,
1299 } = res
1300 {
1301 res = Res::SelfTyAlias {
1302 alias_to: def,
1303 forbid_generic: true,
1304 is_trait_impl,
1305 }
1306 } else {
1307 if let Some(span) = finalize {
1308 let error = match cause {
1309 NoConstantGenericsReason::IsEnumDiscriminant => {
1310 ResolutionError::ParamInEnumDiscriminant {
1311 name: rib_ident.name,
1312 param_kind: ParamKindInEnumDiscriminant::Type,
1313 }
1314 }
1315 NoConstantGenericsReason::NonTrivialConstArg => {
1316 ResolutionError::ParamInNonTrivialAnonConst {
1317 name: rib_ident.name,
1318 param_kind:
1319 ParamKindInNonTrivialAnonConst::Type,
1320 }
1321 }
1322 };
1323 let _: ErrorGuaranteed = self.report_error(span, error);
1324 }
1325
1326 return Res::Err;
1327 }
1328 }
1329
1330 continue;
1331 }
1332
1333 RibKind::Item(has_generic_params, def_kind) => {
1335 (has_generic_params, def_kind)
1336 }
1337 };
1338
1339 if let Some(span) = finalize {
1340 self.report_error(
1341 span,
1342 ResolutionError::GenericParamsFromOuterItem(
1343 res,
1344 has_generic_params,
1345 def_kind,
1346 ),
1347 );
1348 }
1349 return Res::Err;
1350 }
1351 }
1352 Res::Def(DefKind::ConstParam, _) => {
1353 for rib in ribs {
1354 let (has_generic_params, def_kind) = match rib.kind {
1355 RibKind::Normal
1356 | RibKind::Block(..)
1357 | RibKind::FnOrCoroutine
1358 | RibKind::Module(..)
1359 | RibKind::MacroDefinition(..)
1360 | RibKind::InlineAsmSym
1361 | RibKind::AssocItem
1362 | RibKind::ForwardGenericParamBan(_) => continue,
1363
1364 RibKind::ConstParamTy => {
1365 if !self.tcx.features().generic_const_parameter_types() {
1366 if let Some(span) = finalize {
1367 self.report_error(
1368 span,
1369 ResolutionError::ParamInTyOfConstParam {
1370 name: rib_ident.name,
1371 },
1372 );
1373 }
1374 return Res::Err;
1375 } else {
1376 continue;
1377 }
1378 }
1379
1380 RibKind::ConstantItem(trivial, _) => {
1381 if let ConstantHasGenerics::No(cause) = trivial {
1382 if let Some(span) = finalize {
1383 let error = match cause {
1384 NoConstantGenericsReason::IsEnumDiscriminant => {
1385 ResolutionError::ParamInEnumDiscriminant {
1386 name: rib_ident.name,
1387 param_kind: ParamKindInEnumDiscriminant::Const,
1388 }
1389 }
1390 NoConstantGenericsReason::NonTrivialConstArg => {
1391 ResolutionError::ParamInNonTrivialAnonConst {
1392 name: rib_ident.name,
1393 param_kind: ParamKindInNonTrivialAnonConst::Const {
1394 name: rib_ident.name,
1395 },
1396 }
1397 }
1398 };
1399 self.report_error(span, error);
1400 }
1401
1402 return Res::Err;
1403 }
1404
1405 continue;
1406 }
1407
1408 RibKind::Item(has_generic_params, def_kind) => {
1409 (has_generic_params, def_kind)
1410 }
1411 };
1412
1413 if let Some(span) = finalize {
1415 self.report_error(
1416 span,
1417 ResolutionError::GenericParamsFromOuterItem(
1418 res,
1419 has_generic_params,
1420 def_kind,
1421 ),
1422 );
1423 }
1424 return Res::Err;
1425 }
1426 }
1427 _ => {}
1428 }
1429
1430 res
1431 }
1432
1433 #[instrument(level = "debug", skip(self))]
1434 pub(crate) fn maybe_resolve_path<'r>(
1435 self: CmResolver<'r, 'ra, 'tcx>,
1436 path: &[Segment],
1437 opt_ns: Option<Namespace>, parent_scope: &ParentScope<'ra>,
1439 ignore_import: Option<Import<'ra>>,
1440 ) -> PathResult<'ra> {
1441 self.resolve_path_with_ribs(
1442 path,
1443 opt_ns,
1444 parent_scope,
1445 None,
1446 None,
1447 None,
1448 None,
1449 ignore_import,
1450 )
1451 }
1452 #[instrument(level = "debug", skip(self))]
1453 pub(crate) fn resolve_path<'r>(
1454 self: CmResolver<'r, 'ra, 'tcx>,
1455 path: &[Segment],
1456 opt_ns: Option<Namespace>, parent_scope: &ParentScope<'ra>,
1458 finalize: Option<Finalize>,
1459 ignore_binding: Option<NameBinding<'ra>>,
1460 ignore_import: Option<Import<'ra>>,
1461 ) -> PathResult<'ra> {
1462 self.resolve_path_with_ribs(
1463 path,
1464 opt_ns,
1465 parent_scope,
1466 None,
1467 finalize,
1468 None,
1469 ignore_binding,
1470 ignore_import,
1471 )
1472 }
1473
1474 pub(crate) fn resolve_path_with_ribs<'r>(
1475 mut self: CmResolver<'r, 'ra, 'tcx>,
1476 path: &[Segment],
1477 opt_ns: Option<Namespace>, parent_scope: &ParentScope<'ra>,
1479 source: Option<PathSource<'_, '_, '_>>,
1480 finalize: Option<Finalize>,
1481 ribs: Option<&PerNS<Vec<Rib<'ra>>>>,
1482 ignore_binding: Option<NameBinding<'ra>>,
1483 ignore_import: Option<Import<'ra>>,
1484 ) -> PathResult<'ra> {
1485 let mut module = None;
1486 let mut module_had_parse_errors = false;
1487 let mut allow_super = true;
1488 let mut second_binding = None;
1489
1490 let privacy_errors_len = self.privacy_errors.len();
1492 fn record_segment_res<'r, 'ra, 'tcx>(
1493 mut this: CmResolver<'r, 'ra, 'tcx>,
1494 finalize: Option<Finalize>,
1495 res: Res,
1496 id: Option<NodeId>,
1497 ) {
1498 if finalize.is_some()
1499 && let Some(id) = id
1500 && !this.partial_res_map.contains_key(&id)
1501 {
1502 assert!(id != ast::DUMMY_NODE_ID, "Trying to resolve dummy id");
1503 this.get_mut().record_partial_res(id, PartialRes::new(res));
1504 }
1505 }
1506
1507 for (segment_idx, &Segment { ident, id, .. }) in path.iter().enumerate() {
1508 debug!("resolve_path ident {} {:?} {:?}", segment_idx, ident, id);
1509
1510 let is_last = segment_idx + 1 == path.len();
1511 let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };
1512 let name = ident.name;
1513
1514 allow_super &= ns == TypeNS && (name == kw::SelfLower || name == kw::Super);
1515
1516 if ns == TypeNS {
1517 if allow_super && name == kw::Super {
1518 let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();
1519 let self_module = match segment_idx {
1520 0 => Some(self.resolve_self(&mut ctxt, parent_scope.module)),
1521 _ => match module {
1522 Some(ModuleOrUniformRoot::Module(module)) => Some(module),
1523 _ => None,
1524 },
1525 };
1526 if let Some(self_module) = self_module
1527 && let Some(parent) = self_module.parent
1528 {
1529 module =
1530 Some(ModuleOrUniformRoot::Module(self.resolve_self(&mut ctxt, parent)));
1531 continue;
1532 }
1533 return PathResult::failed(
1534 ident,
1535 false,
1536 finalize.is_some(),
1537 module_had_parse_errors,
1538 module,
1539 || ("there are too many leading `super` keywords".to_string(), None),
1540 );
1541 }
1542 if segment_idx == 0 {
1543 if name == kw::SelfLower {
1544 let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();
1545 let self_mod = self.resolve_self(&mut ctxt, parent_scope.module);
1546 if let Some(res) = self_mod.res() {
1547 record_segment_res(self.reborrow(), finalize, res, id);
1548 }
1549 module = Some(ModuleOrUniformRoot::Module(self_mod));
1550 continue;
1551 }
1552 if name == kw::PathRoot && ident.span.at_least_rust_2018() {
1553 module = Some(ModuleOrUniformRoot::ExternPrelude);
1554 continue;
1555 }
1556 if name == kw::PathRoot
1557 && ident.span.is_rust_2015()
1558 && self.tcx.sess.at_least_rust_2018()
1559 {
1560 let crate_root = self.resolve_crate_root(ident);
1562 module = Some(ModuleOrUniformRoot::ModuleAndExternPrelude(crate_root));
1563 continue;
1564 }
1565 if name == kw::PathRoot || name == kw::Crate || name == kw::DollarCrate {
1566 let crate_root = self.resolve_crate_root(ident);
1568 if let Some(res) = crate_root.res() {
1569 record_segment_res(self.reborrow(), finalize, res, id);
1570 }
1571 module = Some(ModuleOrUniformRoot::Module(crate_root));
1572 continue;
1573 }
1574 }
1575 }
1576
1577 if ident.is_path_segment_keyword() && segment_idx != 0 {
1579 return PathResult::failed(
1580 ident,
1581 false,
1582 finalize.is_some(),
1583 module_had_parse_errors,
1584 module,
1585 || {
1586 let name_str = if name == kw::PathRoot {
1587 "crate root".to_string()
1588 } else {
1589 format!("`{name}`")
1590 };
1591 let label = if segment_idx == 1 && path[0].ident.name == kw::PathRoot {
1592 format!("global paths cannot start with {name_str}")
1593 } else {
1594 format!("{name_str} in paths can only be used in start position")
1595 };
1596 (label, None)
1597 },
1598 );
1599 }
1600
1601 let binding = if let Some(module) = module {
1602 self.reborrow()
1603 .resolve_ident_in_module(
1604 module,
1605 ident,
1606 ns,
1607 parent_scope,
1608 finalize,
1609 ignore_binding,
1610 ignore_import,
1611 )
1612 .map_err(|(determinacy, _)| determinacy)
1613 } else if let Some(ribs) = ribs
1614 && let Some(TypeNS | ValueNS) = opt_ns
1615 {
1616 assert!(ignore_import.is_none());
1617 match self.get_mut().resolve_ident_in_lexical_scope(
1618 ident,
1619 ns,
1620 parent_scope,
1621 finalize,
1622 &ribs[ns],
1623 ignore_binding,
1624 ) {
1625 Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
1627 Some(LexicalScopeBinding::Res(res)) => {
1629 record_segment_res(self.reborrow(), finalize, res, id);
1630 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1631 res,
1632 path.len() - 1,
1633 ));
1634 }
1635 _ => Err(Determinacy::determined(finalize.is_some())),
1636 }
1637 } else {
1638 self.reborrow().early_resolve_ident_in_lexical_scope(
1639 ident,
1640 ScopeSet::All(ns),
1641 parent_scope,
1642 finalize,
1643 finalize.is_some(),
1644 ignore_binding,
1645 ignore_import,
1646 )
1647 };
1648
1649 match binding {
1650 Ok(binding) => {
1651 if segment_idx == 1 {
1652 second_binding = Some(binding);
1653 }
1654 let res = binding.res();
1655
1656 if finalize.is_some() {
1660 for error in &mut self.get_mut().privacy_errors[privacy_errors_len..] {
1661 error.outermost_res = Some((res, ident));
1662 error.source = match source {
1663 Some(PathSource::Struct(Some(expr)))
1664 | Some(PathSource::Expr(Some(expr))) => Some(expr.clone()),
1665 _ => None,
1666 };
1667 }
1668 }
1669
1670 let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(res);
1671 if let Some(def_id) = binding.res().module_like_def_id() {
1672 if self.mods_with_parse_errors.contains(&def_id) {
1673 module_had_parse_errors = true;
1674 }
1675 module = Some(ModuleOrUniformRoot::Module(self.expect_module(def_id)));
1676 record_segment_res(self.reborrow(), finalize, res, id);
1677 } else if res == Res::ToolMod && !is_last && opt_ns.is_some() {
1678 if binding.is_import() {
1679 self.dcx().emit_err(errors::ToolModuleImported {
1680 span: ident.span,
1681 import: binding.span,
1682 });
1683 }
1684 let res = Res::NonMacroAttr(NonMacroAttrKind::Tool);
1685 return PathResult::NonModule(PartialRes::new(res));
1686 } else if res == Res::Err {
1687 return PathResult::NonModule(PartialRes::new(Res::Err));
1688 } else if opt_ns.is_some() && (is_last || maybe_assoc) {
1689 if let Some(finalize) = finalize {
1690 self.get_mut().lint_if_path_starts_with_module(
1691 finalize,
1692 path,
1693 second_binding,
1694 );
1695 }
1696 record_segment_res(self.reborrow(), finalize, res, id);
1697 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1698 res,
1699 path.len() - segment_idx - 1,
1700 ));
1701 } else {
1702 return PathResult::failed(
1703 ident,
1704 is_last,
1705 finalize.is_some(),
1706 module_had_parse_errors,
1707 module,
1708 || {
1709 let label = format!(
1710 "`{ident}` is {} {}, not a module",
1711 res.article(),
1712 res.descr()
1713 );
1714 (label, None)
1715 },
1716 );
1717 }
1718 }
1719 Err(Undetermined) => return PathResult::Indeterminate,
1720 Err(Determined) => {
1721 if let Some(ModuleOrUniformRoot::Module(module)) = module
1722 && opt_ns.is_some()
1723 && !module.is_normal()
1724 {
1725 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1726 module.res().unwrap(),
1727 path.len() - segment_idx,
1728 ));
1729 }
1730
1731 let mut this = self.reborrow();
1732 return PathResult::failed(
1733 ident,
1734 is_last,
1735 finalize.is_some(),
1736 module_had_parse_errors,
1737 module,
1738 || {
1739 this.get_mut().report_path_resolution_error(
1740 path,
1741 opt_ns,
1742 parent_scope,
1743 ribs,
1744 ignore_binding,
1745 ignore_import,
1746 module,
1747 segment_idx,
1748 ident,
1749 )
1750 },
1751 );
1752 }
1753 }
1754 }
1755
1756 if let Some(finalize) = finalize {
1757 self.get_mut().lint_if_path_starts_with_module(finalize, path, second_binding);
1758 }
1759
1760 PathResult::Module(match module {
1761 Some(module) => module,
1762 None if path.is_empty() => ModuleOrUniformRoot::CurrentScope,
1763 _ => bug!("resolve_path: non-empty path `{:?}` has no module", path),
1764 })
1765 }
1766}