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