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