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::{ConstantHasGenerics, NoConstantGenericsReason, PathSource, Rib, RibKind};
16use crate::macros::{MacroRulesScope, sub_namespace_match};
17use crate::{
18 AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingKey, CmResolver, Determinacy,
19 Finalize, ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot,
20 NameBinding, NameBindingKind, ParentScope, PathResult, PrivacyError, Res, ResolutionError,
21 Resolver, Scope, ScopeSet, Segment, Stage, Used, Weak, errors,
22};
23
24#[derive(Copy, Clone)]
25pub enum UsePrelude {
26 No,
27 Yes,
28}
29
30impl From<UsePrelude> for bool {
31 fn from(up: UsePrelude) -> bool {
32 matches!(up, UsePrelude::Yes)
33 }
34}
35
36#[derive(Debug, PartialEq, Clone, Copy)]
37enum Shadowing {
38 Restricted,
39 Unrestricted,
40}
41
42impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
43 pub(crate) fn visit_scopes<'r, T>(
47 mut self: CmResolver<'r, 'ra, 'tcx>,
48 scope_set: ScopeSet<'ra>,
49 parent_scope: &ParentScope<'ra>,
50 ctxt: SyntaxContext,
51 derive_fallback_lint_id: Option<NodeId>,
52 mut visitor: impl FnMut(
53 &mut CmResolver<'r, 'ra, 'tcx>,
54 Scope<'ra>,
55 UsePrelude,
56 SyntaxContext,
57 ) -> Option<T>,
58 ) -> Option<T> {
59 let rust_2015 = ctxt.edition().is_rust_2015();
101 let (ns, macro_kind) = match scope_set {
102 ScopeSet::All(ns) | ScopeSet::ModuleAndExternPrelude(ns, _) => (ns, None),
103 ScopeSet::ExternPrelude => (TypeNS, None),
104 ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
105 };
106 let module = match scope_set {
107 ScopeSet::ModuleAndExternPrelude(_, module) => module,
109 _ => parent_scope.module.nearest_item_scope(),
111 };
112 let module_and_extern_prelude = matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..));
113 let extern_prelude = matches!(scope_set, ScopeSet::ExternPrelude);
114 let mut scope = match ns {
115 _ if module_and_extern_prelude => Scope::Module(module, None),
116 _ if extern_prelude => Scope::ExternPreludeItems,
117 TypeNS | ValueNS => Scope::Module(module, None),
118 MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
119 };
120 let mut ctxt = ctxt.normalize_to_macros_2_0();
121 let mut use_prelude = !module.no_implicit_prelude;
122
123 loop {
124 let visit = match scope {
125 Scope::DeriveHelpers(expn_id) => {
127 !(expn_id == parent_scope.expansion && macro_kind == Some(MacroKind::Derive))
128 }
129 Scope::DeriveHelpersCompat => true,
130 Scope::MacroRules(macro_rules_scope) => {
131 while let MacroRulesScope::Invocation(invoc_id) = macro_rules_scope.get() {
136 if let Some(next_scope) = self.output_macro_rules_scopes.get(&invoc_id) {
137 macro_rules_scope.set(next_scope.get());
138 } else {
139 break;
140 }
141 }
142 true
143 }
144 Scope::Module(..) => true,
145 Scope::MacroUsePrelude => use_prelude || rust_2015,
146 Scope::BuiltinAttrs => true,
147 Scope::ExternPreludeItems | Scope::ExternPreludeFlags => {
148 use_prelude || module_and_extern_prelude || extern_prelude
149 }
150 Scope::ToolPrelude => use_prelude,
151 Scope::StdLibPrelude => use_prelude || ns == MacroNS,
152 Scope::BuiltinTypes => true,
153 };
154
155 if visit {
156 let use_prelude = if use_prelude { UsePrelude::Yes } else { UsePrelude::No };
157 if let break_result @ Some(..) = visitor(&mut self, scope, use_prelude, ctxt) {
158 return break_result;
159 }
160 }
161
162 scope = match scope {
163 Scope::DeriveHelpers(LocalExpnId::ROOT) => Scope::DeriveHelpersCompat,
164 Scope::DeriveHelpers(expn_id) => {
165 let expn_data = expn_id.expn_data();
167 match expn_data.kind {
168 ExpnKind::Root
169 | ExpnKind::Macro(MacroKind::Bang | MacroKind::Derive, _) => {
170 Scope::DeriveHelpersCompat
171 }
172 _ => Scope::DeriveHelpers(expn_data.parent.expect_local()),
173 }
174 }
175 Scope::DeriveHelpersCompat => Scope::MacroRules(parent_scope.macro_rules),
176 Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() {
177 MacroRulesScope::Binding(binding) => {
178 Scope::MacroRules(binding.parent_macro_rules_scope)
179 }
180 MacroRulesScope::Invocation(invoc_id) => {
181 Scope::MacroRules(self.invocation_parent_scopes[&invoc_id].macro_rules)
182 }
183 MacroRulesScope::Empty => Scope::Module(module, None),
184 },
185 Scope::Module(..) if module_and_extern_prelude => match ns {
186 TypeNS => {
187 ctxt.adjust(ExpnId::root());
188 Scope::ExternPreludeItems
189 }
190 ValueNS | MacroNS => break,
191 },
192 Scope::Module(module, prev_lint_id) => {
193 use_prelude = !module.no_implicit_prelude;
194 match self.hygienic_lexical_parent(module, &mut ctxt, derive_fallback_lint_id) {
195 Some((parent_module, lint_id)) => {
196 Scope::Module(parent_module, lint_id.or(prev_lint_id))
197 }
198 None => {
199 ctxt.adjust(ExpnId::root());
200 match ns {
201 TypeNS => Scope::ExternPreludeItems,
202 ValueNS => Scope::StdLibPrelude,
203 MacroNS => Scope::MacroUsePrelude,
204 }
205 }
206 }
207 }
208 Scope::MacroUsePrelude => Scope::StdLibPrelude,
209 Scope::BuiltinAttrs => break, Scope::ExternPreludeItems => Scope::ExternPreludeFlags,
211 Scope::ExternPreludeFlags if module_and_extern_prelude || extern_prelude => break,
212 Scope::ExternPreludeFlags => Scope::ToolPrelude,
213 Scope::ToolPrelude => Scope::StdLibPrelude,
214 Scope::StdLibPrelude => match ns {
215 TypeNS => Scope::BuiltinTypes,
216 ValueNS => break, MacroNS => Scope::BuiltinAttrs,
218 },
219 Scope::BuiltinTypes => break, };
221 }
222
223 None
224 }
225
226 fn hygienic_lexical_parent(
227 &self,
228 module: Module<'ra>,
229 ctxt: &mut SyntaxContext,
230 derive_fallback_lint_id: Option<NodeId>,
231 ) -> Option<(Module<'ra>, Option<NodeId>)> {
232 if !module.expansion.outer_expn_is_descendant_of(*ctxt) {
233 return Some((self.expn_def_scope(ctxt.remove_mark()), None));
234 }
235
236 if let ModuleKind::Block = module.kind {
237 return Some((module.parent.unwrap().nearest_item_scope(), None));
238 }
239
240 if derive_fallback_lint_id.is_some()
252 && let Some(parent) = module.parent
253 && module.expansion != parent.expansion
255 && module.expansion.is_descendant_of(parent.expansion)
257 && let Some(def_id) = module.expansion.expn_data().macro_def_id
259 {
260 let ext = &self.get_macro_by_def_id(def_id).ext;
261 if ext.builtin_name.is_none()
262 && ext.macro_kinds() == MacroKinds::DERIVE
263 && parent.expansion.outer_expn_is_descendant_of(*ctxt)
264 {
265 return Some((parent, derive_fallback_lint_id));
266 }
267 }
268
269 None
270 }
271
272 #[instrument(level = "debug", skip(self, ribs))]
290 pub(crate) fn resolve_ident_in_lexical_scope(
291 &mut self,
292 mut ident: Ident,
293 ns: Namespace,
294 parent_scope: &ParentScope<'ra>,
295 finalize: Option<Finalize>,
296 ribs: &[Rib<'ra>],
297 ignore_binding: Option<NameBinding<'ra>>,
298 ) -> Option<LexicalScopeBinding<'ra>> {
299 assert!(ns == TypeNS || ns == ValueNS);
300 let orig_ident = ident;
301 let (general_span, normalized_span) = if ident.name == kw::SelfUpper {
302 let empty_span = ident.span.with_ctxt(SyntaxContext::root());
304 (empty_span, empty_span)
305 } else if ns == TypeNS {
306 let normalized_span = ident.span.normalize_to_macros_2_0();
307 (normalized_span, normalized_span)
308 } else {
309 (ident.span.normalize_to_macro_rules(), ident.span.normalize_to_macros_2_0())
310 };
311 ident.span = general_span;
312 let normalized_ident = Ident { span: normalized_span, ..ident };
313
314 for (i, rib) in ribs.iter().enumerate().rev() {
316 debug!("walk rib\n{:?}", rib.bindings);
317 let rib_ident = if rib.kind.contains_params() { normalized_ident } else { ident };
320 if let Some((original_rib_ident_def, res)) = rib.bindings.get_key_value(&rib_ident) {
321 return Some(LexicalScopeBinding::Res(self.validate_res_from_ribs(
323 i,
324 rib_ident,
325 *res,
326 finalize.map(|finalize| finalize.path_span),
327 *original_rib_ident_def,
328 ribs,
329 )));
330 } else if let RibKind::Block(Some(module)) = rib.kind
331 && let Ok(binding) = self.cm().resolve_ident_in_module_unadjusted(
332 ModuleOrUniformRoot::Module(module),
333 ident,
334 ns,
335 parent_scope,
336 Shadowing::Unrestricted,
337 finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }),
338 ignore_binding,
339 None,
340 )
341 {
342 return Some(LexicalScopeBinding::Item(binding));
344 } else if let RibKind::Module(module) = rib.kind {
345 let parent_scope = &ParentScope { module, ..*parent_scope };
347 let finalize = finalize.map(|f| Finalize { stage: Stage::Late, ..f });
348 return self
349 .cm()
350 .resolve_ident_in_scope_set(
351 orig_ident,
352 ScopeSet::All(ns),
353 parent_scope,
354 finalize,
355 finalize.is_some(),
356 ignore_binding,
357 None,
358 )
359 .ok()
360 .map(LexicalScopeBinding::Item);
361 }
362
363 if let RibKind::MacroDefinition(def) = rib.kind
364 && def == self.macro_def(ident.span.ctxt())
365 {
366 ident.span.remove_mark();
369 }
370 }
371
372 unreachable!()
373 }
374
375 #[instrument(level = "debug", skip(self))]
377 pub(crate) fn resolve_ident_in_scope_set<'r>(
378 self: CmResolver<'r, 'ra, 'tcx>,
379 orig_ident: Ident,
380 scope_set: ScopeSet<'ra>,
381 parent_scope: &ParentScope<'ra>,
382 finalize: Option<Finalize>,
383 force: bool,
384 ignore_binding: Option<NameBinding<'ra>>,
385 ignore_import: Option<Import<'ra>>,
386 ) -> Result<NameBinding<'ra>, Determinacy> {
387 bitflags::bitflags! {
388 #[derive(Clone, Copy)]
389 struct Flags: u8 {
390 const MACRO_RULES = 1 << 0;
391 const MODULE = 1 << 1;
392 const MISC_SUGGEST_CRATE = 1 << 2;
393 const MISC_SUGGEST_SELF = 1 << 3;
394 const MISC_FROM_PRELUDE = 1 << 4;
395 }
396 }
397
398 assert!(force || finalize.is_none()); if orig_ident.is_path_segment_keyword() {
402 return Err(Determinacy::Determined);
403 }
404
405 let (ns, macro_kind) = match scope_set {
406 ScopeSet::All(ns) | ScopeSet::ModuleAndExternPrelude(ns, _) => (ns, None),
407 ScopeSet::ExternPrelude => (TypeNS, None),
408 ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
409 };
410
411 let mut innermost_result: Option<(NameBinding<'_>, Flags)> = None;
423 let mut determinacy = Determinacy::Determined;
424 let mut extern_prelude_item_binding = None;
425 let mut extern_prelude_flag_binding = None;
426 macro finalize_scope() {
428 if innermost_result.is_none() { finalize } else { None }
429 }
430
431 let derive_fallback_lint_id = match finalize {
433 Some(Finalize { node_id, stage: Stage::Late, .. }) => Some(node_id),
434 _ => None,
435 };
436 let break_result = self.visit_scopes(
437 scope_set,
438 parent_scope,
439 orig_ident.span.ctxt(),
440 derive_fallback_lint_id,
441 |this, scope, use_prelude, ctxt| {
442 let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt));
443 let result = match scope {
444 Scope::DeriveHelpers(expn_id) => {
445 if let Some(binding) = this.helper_attrs.get(&expn_id).and_then(|attrs| {
446 attrs.iter().rfind(|(i, _)| ident == *i).map(|(_, binding)| *binding)
447 }) {
448 Ok((binding, Flags::empty()))
449 } else {
450 Err(Determinacy::Determined)
451 }
452 }
453 Scope::DeriveHelpersCompat => {
454 let mut result = Err(Determinacy::Determined);
455 for derive in parent_scope.derives {
456 let parent_scope = &ParentScope { derives: &[], ..*parent_scope };
457 match this.reborrow().resolve_macro_path(
458 derive,
459 MacroKind::Derive,
460 parent_scope,
461 true,
462 force,
463 ignore_import,
464 None,
465 ) {
466 Ok((Some(ext), _)) => {
467 if ext.helper_attrs.contains(&ident.name) {
468 let binding = this.arenas.new_pub_res_binding(
469 Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat),
470 derive.span,
471 LocalExpnId::ROOT,
472 );
473 result = Ok((binding, Flags::empty()));
474 break;
475 }
476 }
477 Ok(_) | Err(Determinacy::Determined) => {}
478 Err(Determinacy::Undetermined) => {
479 result = Err(Determinacy::Undetermined)
480 }
481 }
482 }
483 result
484 }
485 Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() {
486 MacroRulesScope::Binding(macro_rules_binding)
487 if ident == macro_rules_binding.ident =>
488 {
489 Ok((macro_rules_binding.binding, Flags::MACRO_RULES))
490 }
491 MacroRulesScope::Invocation(_) => Err(Determinacy::Undetermined),
492 _ => Err(Determinacy::Determined),
493 },
494 Scope::Module(module, derive_fallback_lint_id) => {
495 let (adjusted_parent_scope, adjusted_finalize) =
496 if matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..)) {
497 (parent_scope, finalize_scope!())
498 } else {
499 (
500 &ParentScope { module, ..*parent_scope },
501 finalize_scope!().map(|f| Finalize { used: Used::Scope, ..f }),
502 )
503 };
504 let binding = this.reborrow().resolve_ident_in_module_unadjusted(
505 ModuleOrUniformRoot::Module(module),
506 ident,
507 ns,
508 adjusted_parent_scope,
509 Shadowing::Restricted,
510 adjusted_finalize,
511 ignore_binding,
512 ignore_import,
513 );
514 match binding {
515 Ok(binding) => {
516 if let Some(lint_id) = derive_fallback_lint_id {
517 this.get_mut().lint_buffer.buffer_lint(
518 PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
519 lint_id,
520 orig_ident.span,
521 errors::ProcMacroDeriveResolutionFallback {
522 span: orig_ident.span,
523 ns_descr: ns.descr(),
524 ident,
525 },
526 );
527 }
528 let misc_flags = if module == this.graph_root {
529 Flags::MISC_SUGGEST_CRATE
530 } else if module.is_normal() {
531 Flags::MISC_SUGGEST_SELF
532 } else {
533 Flags::empty()
534 };
535 Ok((binding, Flags::MODULE | misc_flags))
536 }
537 Err((Determinacy::Undetermined, Weak::No)) => {
538 return Some(Err(Determinacy::determined(force)));
539 }
540 Err((Determinacy::Undetermined, Weak::Yes)) => {
541 Err(Determinacy::Undetermined)
542 }
543 Err((Determinacy::Determined, _)) => Err(Determinacy::Determined),
544 }
545 }
546 Scope::MacroUsePrelude => {
547 match this.macro_use_prelude.get(&ident.name).cloned() {
548 Some(binding) => Ok((binding, Flags::MISC_FROM_PRELUDE)),
549 None => Err(Determinacy::determined(
550 this.graph_root.unexpanded_invocations.borrow().is_empty(),
551 )),
552 }
553 }
554 Scope::BuiltinAttrs => match this.builtin_attrs_bindings.get(&ident.name) {
555 Some(binding) => Ok((*binding, Flags::empty())),
556 None => Err(Determinacy::Determined),
557 },
558 Scope::ExternPreludeItems => {
559 match this
560 .reborrow()
561 .extern_prelude_get_item(ident, finalize_scope!().is_some())
562 {
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 {
681 Some(AmbiguityKind::MacroRulesVsModularized)
682 } else if flags.contains(Flags::MACRO_RULES)
683 && innermost_flags.contains(Flags::MODULE)
684 {
685 span_bug!(
691 orig_ident.span,
692 "ambiguous scoped macro resolutions with path-based \
693 scope resolution as first candidate"
694 )
695 } else if innermost_binding.is_glob_import() {
696 Some(AmbiguityKind::GlobVsOuter)
697 } else if innermost_binding
698 .may_appear_after(parent_scope.expansion, binding)
699 {
700 Some(AmbiguityKind::MoreExpandedVsOuter)
701 } else {
702 None
703 };
704 let issue_145575_hack = Some(binding)
708 == extern_prelude_flag_binding
709 && extern_prelude_item_binding.is_some()
710 && extern_prelude_item_binding != Some(innermost_binding);
711 if let Some(kind) = ambiguity_error_kind
712 && !issue_145575_hack
713 {
714 let misc = |f: Flags| {
715 if f.contains(Flags::MISC_SUGGEST_CRATE) {
716 AmbiguityErrorMisc::SuggestCrate
717 } else if f.contains(Flags::MISC_SUGGEST_SELF) {
718 AmbiguityErrorMisc::SuggestSelf
719 } else if f.contains(Flags::MISC_FROM_PRELUDE) {
720 AmbiguityErrorMisc::FromPrelude
721 } else {
722 AmbiguityErrorMisc::None
723 }
724 };
725 this.get_mut().ambiguity_errors.push(AmbiguityError {
726 kind,
727 ident: orig_ident,
728 b1: innermost_binding,
729 b2: binding,
730 warning: false,
731 misc1: misc(innermost_flags),
732 misc2: misc(flags),
733 });
734 return Some(Ok(innermost_binding));
735 }
736 }
737 } else {
738 innermost_result = Some((binding, flags));
740 }
741 }
742 Err(Determinacy::Determined) => {}
743 Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined,
744 }
745
746 None
747 },
748 );
749
750 if let Some(break_result) = break_result {
751 return break_result;
752 }
753
754 if let Some((binding, _)) = innermost_result {
756 return Ok(binding);
757 }
758
759 Err(Determinacy::determined(determinacy == Determinacy::Determined || force))
760 }
761
762 #[instrument(level = "debug", skip(self))]
763 pub(crate) fn maybe_resolve_ident_in_module<'r>(
764 self: CmResolver<'r, 'ra, 'tcx>,
765 module: ModuleOrUniformRoot<'ra>,
766 ident: Ident,
767 ns: Namespace,
768 parent_scope: &ParentScope<'ra>,
769 ignore_import: Option<Import<'ra>>,
770 ) -> Result<NameBinding<'ra>, Determinacy> {
771 self.resolve_ident_in_module(module, ident, ns, parent_scope, None, None, ignore_import)
772 .map_err(|(determinacy, _)| determinacy)
773 }
774
775 #[instrument(level = "debug", skip(self))]
776 pub(crate) fn resolve_ident_in_module<'r>(
777 self: CmResolver<'r, 'ra, 'tcx>,
778 module: ModuleOrUniformRoot<'ra>,
779 mut ident: Ident,
780 ns: Namespace,
781 parent_scope: &ParentScope<'ra>,
782 finalize: Option<Finalize>,
783 ignore_binding: Option<NameBinding<'ra>>,
784 ignore_import: Option<Import<'ra>>,
785 ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
786 let tmp_parent_scope;
787 let mut adjusted_parent_scope = parent_scope;
788 match module {
789 ModuleOrUniformRoot::Module(m) => {
790 if let Some(def) = ident.span.normalize_to_macros_2_0_and_adjust(m.expansion) {
791 tmp_parent_scope =
792 ParentScope { module: self.expn_def_scope(def), ..*parent_scope };
793 adjusted_parent_scope = &tmp_parent_scope;
794 }
795 }
796 ModuleOrUniformRoot::ExternPrelude => {
797 ident.span.normalize_to_macros_2_0_and_adjust(ExpnId::root());
798 }
799 ModuleOrUniformRoot::ModuleAndExternPrelude(..) | ModuleOrUniformRoot::CurrentScope => {
800 }
802 }
803 self.resolve_ident_in_module_unadjusted(
804 module,
805 ident,
806 ns,
807 adjusted_parent_scope,
808 Shadowing::Unrestricted,
809 finalize,
810 ignore_binding,
811 ignore_import,
812 )
813 }
814 #[instrument(level = "debug", skip(self))]
817 fn resolve_ident_in_module_unadjusted<'r>(
818 mut self: CmResolver<'r, 'ra, 'tcx>,
819 module: ModuleOrUniformRoot<'ra>,
820 ident: Ident,
821 ns: Namespace,
822 parent_scope: &ParentScope<'ra>,
823 shadowing: Shadowing,
824 finalize: Option<Finalize>,
825 ignore_binding: Option<NameBinding<'ra>>,
828 ignore_import: Option<Import<'ra>>,
829 ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
830 let module = match module {
831 ModuleOrUniformRoot::Module(module) => module,
832 ModuleOrUniformRoot::ModuleAndExternPrelude(module) => {
833 assert_eq!(shadowing, Shadowing::Unrestricted);
834 let binding = self.resolve_ident_in_scope_set(
835 ident,
836 ScopeSet::ModuleAndExternPrelude(ns, module),
837 parent_scope,
838 finalize,
839 finalize.is_some(),
840 ignore_binding,
841 ignore_import,
842 );
843 return binding.map_err(|determinacy| (determinacy, Weak::No));
844 }
845 ModuleOrUniformRoot::ExternPrelude => {
846 assert_eq!(shadowing, Shadowing::Unrestricted);
847 return if ns != TypeNS {
848 Err((Determined, Weak::No))
849 } else {
850 let binding = self.resolve_ident_in_scope_set(
851 ident,
852 ScopeSet::ExternPrelude,
853 parent_scope,
854 finalize,
855 finalize.is_some(),
856 ignore_binding,
857 ignore_import,
858 );
859 return binding.map_err(|determinacy| (determinacy, Weak::No));
860 };
861 }
862 ModuleOrUniformRoot::CurrentScope => {
863 assert_eq!(shadowing, Shadowing::Unrestricted);
864 if ns == TypeNS {
865 if ident.name == kw::Crate || ident.name == kw::DollarCrate {
866 let module = self.resolve_crate_root(ident);
867 return Ok(module.self_binding.unwrap());
868 } else if ident.name == kw::Super || ident.name == kw::SelfLower {
869 }
873 }
874
875 let binding = self.resolve_ident_in_scope_set(
876 ident,
877 ScopeSet::All(ns),
878 parent_scope,
879 finalize,
880 finalize.is_some(),
881 ignore_binding,
882 ignore_import,
883 );
884 return binding.map_err(|determinacy| (determinacy, Weak::No));
885 }
886 };
887
888 let key = BindingKey::new(ident, ns);
889 let resolution = &*self
893 .resolution_or_default(module, key)
894 .try_borrow_mut_unchecked()
895 .map_err(|_| (Determined, Weak::No))?;
896
897 let binding = [resolution.non_glob_binding, resolution.glob_binding]
902 .into_iter()
903 .find_map(|binding| if binding == ignore_binding { None } else { binding });
904
905 if let Some(finalize) = finalize {
906 return self.get_mut().finalize_module_binding(
907 ident,
908 binding,
909 if resolution.non_glob_binding.is_some() { resolution.glob_binding } else { None },
910 parent_scope,
911 module,
912 finalize,
913 shadowing,
914 );
915 }
916
917 let check_usable = |this: CmResolver<'r, 'ra, 'tcx>, binding: NameBinding<'ra>| {
918 let usable = this.is_accessible_from(binding.vis, parent_scope.module);
919 if usable { Ok(binding) } else { Err((Determined, Weak::No)) }
920 };
921
922 if let Some(binding) = binding
924 && !binding.is_glob_import()
925 {
926 return check_usable(self, binding);
927 }
928
929 if self.reborrow().single_import_can_define_name(
934 &resolution,
935 binding,
936 ns,
937 ignore_import,
938 ignore_binding,
939 parent_scope,
940 ) {
941 return Err((Undetermined, Weak::No));
942 }
943
944 if let Some(binding) = binding {
957 if binding.determined() || ns == MacroNS || shadowing == Shadowing::Restricted {
958 return check_usable(self, binding);
959 } else {
960 return Err((Undetermined, Weak::No));
961 }
962 }
963
964 if !module.unexpanded_invocations.borrow().is_empty() {
975 return Err((Undetermined, Weak::Yes));
976 }
977
978 for glob_import in module.globs.borrow().iter() {
981 if ignore_import == Some(*glob_import) {
982 continue;
983 }
984 if !self.is_accessible_from(glob_import.vis, parent_scope.module) {
985 continue;
986 }
987 let module = match glob_import.imported_module.get() {
988 Some(ModuleOrUniformRoot::Module(module)) => module,
989 Some(_) => continue,
990 None => return Err((Undetermined, Weak::Yes)),
991 };
992 let tmp_parent_scope;
993 let (mut adjusted_parent_scope, mut ident) =
994 (parent_scope, ident.normalize_to_macros_2_0());
995 match ident.span.glob_adjust(module.expansion, glob_import.span) {
996 Some(Some(def)) => {
997 tmp_parent_scope =
998 ParentScope { module: self.expn_def_scope(def), ..*parent_scope };
999 adjusted_parent_scope = &tmp_parent_scope;
1000 }
1001 Some(None) => {}
1002 None => continue,
1003 };
1004 let result = self.reborrow().resolve_ident_in_module_unadjusted(
1005 ModuleOrUniformRoot::Module(module),
1006 ident,
1007 ns,
1008 adjusted_parent_scope,
1009 Shadowing::Unrestricted,
1010 None,
1011 ignore_binding,
1012 ignore_import,
1013 );
1014
1015 match result {
1016 Err((Determined, _)) => continue,
1017 Ok(binding)
1018 if !self.is_accessible_from(binding.vis, glob_import.parent_scope.module) =>
1019 {
1020 continue;
1021 }
1022 Ok(_) | Err((Undetermined, _)) => return Err((Undetermined, Weak::Yes)),
1023 }
1024 }
1025
1026 Err((Determined, Weak::No))
1028 }
1029
1030 fn finalize_module_binding(
1031 &mut self,
1032 ident: Ident,
1033 binding: Option<NameBinding<'ra>>,
1034 shadowed_glob: Option<NameBinding<'ra>>,
1035 parent_scope: &ParentScope<'ra>,
1036 module: Module<'ra>,
1037 finalize: Finalize,
1038 shadowing: Shadowing,
1039 ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
1040 let Finalize { path_span, report_private, used, root_span, .. } = finalize;
1041
1042 let Some(binding) = binding else {
1043 return Err((Determined, Weak::No));
1044 };
1045
1046 if !self.is_accessible_from(binding.vis, parent_scope.module) {
1047 if report_private {
1048 self.privacy_errors.push(PrivacyError {
1049 ident,
1050 binding,
1051 dedup_span: path_span,
1052 outermost_res: None,
1053 source: None,
1054 parent_scope: *parent_scope,
1055 single_nested: path_span != root_span,
1056 });
1057 } else {
1058 return Err((Determined, Weak::No));
1059 }
1060 }
1061
1062 if let Some(shadowed_glob) = shadowed_glob
1064 && shadowing == Shadowing::Restricted
1065 && finalize.stage == Stage::Early
1066 && binding.expansion != LocalExpnId::ROOT
1067 && binding.res() != shadowed_glob.res()
1068 {
1069 self.ambiguity_errors.push(AmbiguityError {
1070 kind: AmbiguityKind::GlobVsExpanded,
1071 ident,
1072 b1: binding,
1073 b2: shadowed_glob,
1074 warning: false,
1075 misc1: AmbiguityErrorMisc::None,
1076 misc2: AmbiguityErrorMisc::None,
1077 });
1078 }
1079
1080 if shadowing == Shadowing::Unrestricted
1081 && binding.expansion != LocalExpnId::ROOT
1082 && let NameBindingKind::Import { import, .. } = binding.kind
1083 && matches!(import.kind, ImportKind::MacroExport)
1084 {
1085 self.macro_expanded_macro_export_errors.insert((path_span, binding.span));
1086 }
1087
1088 if let Res::Def(_, def_id) = binding.res() {
1092 let struct_ctor = match def_id.as_local() {
1093 Some(def_id) => self.struct_constructors.get(&def_id).cloned(),
1094 None => {
1095 let ctor = self.cstore().ctor_untracked(def_id);
1096 ctor.map(|(ctor_kind, ctor_def_id)| {
1097 let ctor_res = Res::Def(
1098 DefKind::Ctor(rustc_hir::def::CtorOf::Struct, ctor_kind),
1099 ctor_def_id,
1100 );
1101 let ctor_vis = self.tcx.visibility(ctor_def_id);
1102 let field_visibilities = self
1103 .tcx
1104 .associated_item_def_ids(def_id)
1105 .iter()
1106 .map(|field_id| self.tcx.visibility(field_id))
1107 .collect();
1108 (ctor_res, ctor_vis, field_visibilities)
1109 })
1110 }
1111 };
1112 if let Some((_, _, fields)) = struct_ctor
1113 && fields.iter().any(|vis| !self.is_accessible_from(*vis, module))
1114 {
1115 self.inaccessible_ctor_reexport.insert(path_span, binding.span);
1116 }
1117 }
1118
1119 self.record_use(ident, binding, used);
1120 return Ok(binding);
1121 }
1122
1123 fn single_import_can_define_name<'r>(
1126 mut self: CmResolver<'r, 'ra, 'tcx>,
1127 resolution: &NameResolution<'ra>,
1128 binding: Option<NameBinding<'ra>>,
1129 ns: Namespace,
1130 ignore_import: Option<Import<'ra>>,
1131 ignore_binding: Option<NameBinding<'ra>>,
1132 parent_scope: &ParentScope<'ra>,
1133 ) -> bool {
1134 for single_import in &resolution.single_imports {
1135 if ignore_import == Some(*single_import) {
1136 continue;
1137 }
1138 if !self.is_accessible_from(single_import.vis, parent_scope.module) {
1139 continue;
1140 }
1141 if let Some(ignored) = ignore_binding
1142 && let NameBindingKind::Import { import, .. } = ignored.kind
1143 && import == *single_import
1144 {
1145 continue;
1146 }
1147
1148 let Some(module) = single_import.imported_module.get() else {
1149 return true;
1150 };
1151 let ImportKind::Single { source, target, bindings, .. } = &single_import.kind else {
1152 unreachable!();
1153 };
1154 if source != target {
1155 if bindings.iter().all(|binding| binding.get().binding().is_none()) {
1156 return true;
1157 } else if bindings[ns].get().binding().is_none() && binding.is_some() {
1158 return true;
1159 }
1160 }
1161
1162 match self.reborrow().resolve_ident_in_module(
1163 module,
1164 *source,
1165 ns,
1166 &single_import.parent_scope,
1167 None,
1168 ignore_binding,
1169 ignore_import,
1170 ) {
1171 Err((Determined, _)) => continue,
1172 Ok(binding)
1173 if !self.is_accessible_from(binding.vis, single_import.parent_scope.module) =>
1174 {
1175 continue;
1176 }
1177 Ok(_) | Err((Undetermined, _)) => {
1178 return true;
1179 }
1180 }
1181 }
1182
1183 false
1184 }
1185
1186 #[instrument(level = "debug", skip(self, all_ribs))]
1188 fn validate_res_from_ribs(
1189 &mut self,
1190 rib_index: usize,
1191 rib_ident: Ident,
1192 mut res: Res,
1193 finalize: Option<Span>,
1194 original_rib_ident_def: Ident,
1195 all_ribs: &[Rib<'ra>],
1196 ) -> Res {
1197 debug!("validate_res_from_ribs({:?})", res);
1198 let ribs = &all_ribs[rib_index + 1..];
1199
1200 if let RibKind::ForwardGenericParamBan(reason) = all_ribs[rib_index].kind {
1203 if let Some(span) = finalize {
1204 let res_error = if rib_ident.name == kw::SelfUpper {
1205 ResolutionError::ForwardDeclaredSelf(reason)
1206 } else {
1207 ResolutionError::ForwardDeclaredGenericParam(rib_ident.name, reason)
1208 };
1209 self.report_error(span, res_error);
1210 }
1211 assert_eq!(res, Res::Err);
1212 return Res::Err;
1213 }
1214
1215 match res {
1216 Res::Local(_) => {
1217 use ResolutionError::*;
1218 let mut res_err = None;
1219
1220 for rib in ribs {
1221 match rib.kind {
1222 RibKind::Normal
1223 | RibKind::Block(..)
1224 | RibKind::FnOrCoroutine
1225 | RibKind::Module(..)
1226 | RibKind::MacroDefinition(..)
1227 | RibKind::ForwardGenericParamBan(_) => {
1228 }
1230 RibKind::Item(..) | RibKind::AssocItem => {
1231 if let Some(span) = finalize {
1235 res_err = Some((span, CannotCaptureDynamicEnvironmentInFnItem));
1240 }
1241 }
1242 RibKind::ConstantItem(_, item) => {
1243 if let Some(span) = finalize {
1245 let (span, resolution_error) = match item {
1246 None if rib_ident.name == kw::SelfLower => {
1247 (span, LowercaseSelf)
1248 }
1249 None => {
1250 let sm = self.tcx.sess.source_map();
1256 let type_span = match sm.span_look_ahead(
1257 original_rib_ident_def.span,
1258 ":",
1259 None,
1260 ) {
1261 None => {
1262 Some(original_rib_ident_def.span.shrink_to_hi())
1263 }
1264 Some(_) => None,
1265 };
1266 (
1267 rib_ident.span,
1268 AttemptToUseNonConstantValueInConstant {
1269 ident: original_rib_ident_def,
1270 suggestion: "const",
1271 current: "let",
1272 type_span,
1273 },
1274 )
1275 }
1276 Some((ident, kind)) => (
1277 span,
1278 AttemptToUseNonConstantValueInConstant {
1279 ident,
1280 suggestion: "let",
1281 current: kind.as_str(),
1282 type_span: None,
1283 },
1284 ),
1285 };
1286 self.report_error(span, resolution_error);
1287 }
1288 return Res::Err;
1289 }
1290 RibKind::ConstParamTy => {
1291 if let Some(span) = finalize {
1292 self.report_error(
1293 span,
1294 ParamInTyOfConstParam { name: rib_ident.name },
1295 );
1296 }
1297 return Res::Err;
1298 }
1299 RibKind::InlineAsmSym => {
1300 if let Some(span) = finalize {
1301 self.report_error(span, InvalidAsmSym);
1302 }
1303 return Res::Err;
1304 }
1305 }
1306 }
1307 if let Some((span, res_err)) = res_err {
1308 self.report_error(span, res_err);
1309 return Res::Err;
1310 }
1311 }
1312 Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {
1313 for rib in ribs {
1314 let (has_generic_params, def_kind) = match rib.kind {
1315 RibKind::Normal
1316 | RibKind::Block(..)
1317 | RibKind::FnOrCoroutine
1318 | RibKind::Module(..)
1319 | RibKind::MacroDefinition(..)
1320 | RibKind::InlineAsmSym
1321 | RibKind::AssocItem
1322 | RibKind::ForwardGenericParamBan(_) => {
1323 continue;
1325 }
1326
1327 RibKind::ConstParamTy => {
1328 if !self.tcx.features().generic_const_parameter_types() {
1329 if let Some(span) = finalize {
1330 self.report_error(
1331 span,
1332 ResolutionError::ParamInTyOfConstParam {
1333 name: rib_ident.name,
1334 },
1335 );
1336 }
1337 return Res::Err;
1338 } else {
1339 continue;
1340 }
1341 }
1342
1343 RibKind::ConstantItem(trivial, _) => {
1344 if let ConstantHasGenerics::No(cause) = trivial {
1345 if let Res::SelfTyAlias {
1350 alias_to: def,
1351 forbid_generic: _,
1352 is_trait_impl,
1353 } = res
1354 {
1355 res = Res::SelfTyAlias {
1356 alias_to: def,
1357 forbid_generic: true,
1358 is_trait_impl,
1359 }
1360 } else {
1361 if let Some(span) = finalize {
1362 let error = match cause {
1363 NoConstantGenericsReason::IsEnumDiscriminant => {
1364 ResolutionError::ParamInEnumDiscriminant {
1365 name: rib_ident.name,
1366 param_kind: ParamKindInEnumDiscriminant::Type,
1367 }
1368 }
1369 NoConstantGenericsReason::NonTrivialConstArg => {
1370 ResolutionError::ParamInNonTrivialAnonConst {
1371 name: rib_ident.name,
1372 param_kind:
1373 ParamKindInNonTrivialAnonConst::Type,
1374 }
1375 }
1376 };
1377 let _: ErrorGuaranteed = self.report_error(span, error);
1378 }
1379
1380 return Res::Err;
1381 }
1382 }
1383
1384 continue;
1385 }
1386
1387 RibKind::Item(has_generic_params, def_kind) => {
1389 (has_generic_params, def_kind)
1390 }
1391 };
1392
1393 if let Some(span) = finalize {
1394 self.report_error(
1395 span,
1396 ResolutionError::GenericParamsFromOuterItem(
1397 res,
1398 has_generic_params,
1399 def_kind,
1400 ),
1401 );
1402 }
1403 return Res::Err;
1404 }
1405 }
1406 Res::Def(DefKind::ConstParam, _) => {
1407 for rib in ribs {
1408 let (has_generic_params, def_kind) = match rib.kind {
1409 RibKind::Normal
1410 | RibKind::Block(..)
1411 | RibKind::FnOrCoroutine
1412 | RibKind::Module(..)
1413 | RibKind::MacroDefinition(..)
1414 | RibKind::InlineAsmSym
1415 | RibKind::AssocItem
1416 | RibKind::ForwardGenericParamBan(_) => continue,
1417
1418 RibKind::ConstParamTy => {
1419 if !self.tcx.features().generic_const_parameter_types() {
1420 if let Some(span) = finalize {
1421 self.report_error(
1422 span,
1423 ResolutionError::ParamInTyOfConstParam {
1424 name: rib_ident.name,
1425 },
1426 );
1427 }
1428 return Res::Err;
1429 } else {
1430 continue;
1431 }
1432 }
1433
1434 RibKind::ConstantItem(trivial, _) => {
1435 if let ConstantHasGenerics::No(cause) = trivial {
1436 if let Some(span) = finalize {
1437 let error = match cause {
1438 NoConstantGenericsReason::IsEnumDiscriminant => {
1439 ResolutionError::ParamInEnumDiscriminant {
1440 name: rib_ident.name,
1441 param_kind: ParamKindInEnumDiscriminant::Const,
1442 }
1443 }
1444 NoConstantGenericsReason::NonTrivialConstArg => {
1445 ResolutionError::ParamInNonTrivialAnonConst {
1446 name: rib_ident.name,
1447 param_kind: ParamKindInNonTrivialAnonConst::Const {
1448 name: rib_ident.name,
1449 },
1450 }
1451 }
1452 };
1453 self.report_error(span, error);
1454 }
1455
1456 return Res::Err;
1457 }
1458
1459 continue;
1460 }
1461
1462 RibKind::Item(has_generic_params, def_kind) => {
1463 (has_generic_params, def_kind)
1464 }
1465 };
1466
1467 if let Some(span) = finalize {
1469 self.report_error(
1470 span,
1471 ResolutionError::GenericParamsFromOuterItem(
1472 res,
1473 has_generic_params,
1474 def_kind,
1475 ),
1476 );
1477 }
1478 return Res::Err;
1479 }
1480 }
1481 _ => {}
1482 }
1483
1484 res
1485 }
1486
1487 #[instrument(level = "debug", skip(self))]
1488 pub(crate) fn maybe_resolve_path<'r>(
1489 self: CmResolver<'r, 'ra, 'tcx>,
1490 path: &[Segment],
1491 opt_ns: Option<Namespace>, parent_scope: &ParentScope<'ra>,
1493 ignore_import: Option<Import<'ra>>,
1494 ) -> PathResult<'ra> {
1495 self.resolve_path_with_ribs(
1496 path,
1497 opt_ns,
1498 parent_scope,
1499 None,
1500 None,
1501 None,
1502 None,
1503 ignore_import,
1504 )
1505 }
1506 #[instrument(level = "debug", skip(self))]
1507 pub(crate) fn resolve_path<'r>(
1508 self: CmResolver<'r, 'ra, 'tcx>,
1509 path: &[Segment],
1510 opt_ns: Option<Namespace>, parent_scope: &ParentScope<'ra>,
1512 finalize: Option<Finalize>,
1513 ignore_binding: Option<NameBinding<'ra>>,
1514 ignore_import: Option<Import<'ra>>,
1515 ) -> PathResult<'ra> {
1516 self.resolve_path_with_ribs(
1517 path,
1518 opt_ns,
1519 parent_scope,
1520 None,
1521 finalize,
1522 None,
1523 ignore_binding,
1524 ignore_import,
1525 )
1526 }
1527
1528 pub(crate) fn resolve_path_with_ribs<'r>(
1529 mut self: CmResolver<'r, 'ra, 'tcx>,
1530 path: &[Segment],
1531 opt_ns: Option<Namespace>, parent_scope: &ParentScope<'ra>,
1533 source: Option<PathSource<'_, '_, '_>>,
1534 finalize: Option<Finalize>,
1535 ribs: Option<&PerNS<Vec<Rib<'ra>>>>,
1536 ignore_binding: Option<NameBinding<'ra>>,
1537 ignore_import: Option<Import<'ra>>,
1538 ) -> PathResult<'ra> {
1539 let mut module = None;
1540 let mut module_had_parse_errors = false;
1541 let mut allow_super = true;
1542 let mut second_binding = None;
1543
1544 let privacy_errors_len = self.privacy_errors.len();
1546 fn record_segment_res<'r, 'ra, 'tcx>(
1547 mut this: CmResolver<'r, 'ra, 'tcx>,
1548 finalize: Option<Finalize>,
1549 res: Res,
1550 id: Option<NodeId>,
1551 ) {
1552 if finalize.is_some()
1553 && let Some(id) = id
1554 && !this.partial_res_map.contains_key(&id)
1555 {
1556 assert!(id != ast::DUMMY_NODE_ID, "Trying to resolve dummy id");
1557 this.get_mut().record_partial_res(id, PartialRes::new(res));
1558 }
1559 }
1560
1561 for (segment_idx, &Segment { ident, id, .. }) in path.iter().enumerate() {
1562 debug!("resolve_path ident {} {:?} {:?}", segment_idx, ident, id);
1563
1564 let is_last = segment_idx + 1 == path.len();
1565 let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };
1566 let name = ident.name;
1567
1568 allow_super &= ns == TypeNS && (name == kw::SelfLower || name == kw::Super);
1569
1570 if ns == TypeNS {
1571 if allow_super && name == kw::Super {
1572 let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();
1573 let self_module = match segment_idx {
1574 0 => Some(self.resolve_self(&mut ctxt, parent_scope.module)),
1575 _ => match module {
1576 Some(ModuleOrUniformRoot::Module(module)) => Some(module),
1577 _ => None,
1578 },
1579 };
1580 if let Some(self_module) = self_module
1581 && let Some(parent) = self_module.parent
1582 {
1583 module =
1584 Some(ModuleOrUniformRoot::Module(self.resolve_self(&mut ctxt, parent)));
1585 continue;
1586 }
1587 return PathResult::failed(
1588 ident,
1589 false,
1590 finalize.is_some(),
1591 module_had_parse_errors,
1592 module,
1593 || ("there are too many leading `super` keywords".to_string(), None),
1594 );
1595 }
1596 if segment_idx == 0 {
1597 if name == kw::SelfLower {
1598 let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();
1599 let self_mod = self.resolve_self(&mut ctxt, parent_scope.module);
1600 if let Some(res) = self_mod.res() {
1601 record_segment_res(self.reborrow(), finalize, res, id);
1602 }
1603 module = Some(ModuleOrUniformRoot::Module(self_mod));
1604 continue;
1605 }
1606 if name == kw::PathRoot && ident.span.at_least_rust_2018() {
1607 module = Some(ModuleOrUniformRoot::ExternPrelude);
1608 continue;
1609 }
1610 if name == kw::PathRoot
1611 && ident.span.is_rust_2015()
1612 && self.tcx.sess.at_least_rust_2018()
1613 {
1614 let crate_root = self.resolve_crate_root(ident);
1616 module = Some(ModuleOrUniformRoot::ModuleAndExternPrelude(crate_root));
1617 continue;
1618 }
1619 if name == kw::PathRoot || name == kw::Crate || name == kw::DollarCrate {
1620 let crate_root = self.resolve_crate_root(ident);
1622 if let Some(res) = crate_root.res() {
1623 record_segment_res(self.reborrow(), finalize, res, id);
1624 }
1625 module = Some(ModuleOrUniformRoot::Module(crate_root));
1626 continue;
1627 }
1628 }
1629 }
1630
1631 if ident.is_path_segment_keyword() && segment_idx != 0 {
1633 return PathResult::failed(
1634 ident,
1635 false,
1636 finalize.is_some(),
1637 module_had_parse_errors,
1638 module,
1639 || {
1640 let name_str = if name == kw::PathRoot {
1641 "crate root".to_string()
1642 } else {
1643 format!("`{name}`")
1644 };
1645 let label = if segment_idx == 1 && path[0].ident.name == kw::PathRoot {
1646 format!("global paths cannot start with {name_str}")
1647 } else {
1648 format!("{name_str} in paths can only be used in start position")
1649 };
1650 (label, None)
1651 },
1652 );
1653 }
1654
1655 let binding = if let Some(module) = module {
1656 self.reborrow()
1657 .resolve_ident_in_module(
1658 module,
1659 ident,
1660 ns,
1661 parent_scope,
1662 finalize,
1663 ignore_binding,
1664 ignore_import,
1665 )
1666 .map_err(|(determinacy, _)| determinacy)
1667 } else if let Some(ribs) = ribs
1668 && let Some(TypeNS | ValueNS) = opt_ns
1669 {
1670 assert!(ignore_import.is_none());
1671 match self.get_mut().resolve_ident_in_lexical_scope(
1672 ident,
1673 ns,
1674 parent_scope,
1675 finalize,
1676 &ribs[ns],
1677 ignore_binding,
1678 ) {
1679 Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
1681 Some(LexicalScopeBinding::Res(res)) => {
1683 record_segment_res(self.reborrow(), finalize, res, id);
1684 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1685 res,
1686 path.len() - 1,
1687 ));
1688 }
1689 _ => Err(Determinacy::determined(finalize.is_some())),
1690 }
1691 } else {
1692 self.reborrow().resolve_ident_in_scope_set(
1693 ident,
1694 ScopeSet::All(ns),
1695 parent_scope,
1696 finalize,
1697 finalize.is_some(),
1698 ignore_binding,
1699 ignore_import,
1700 )
1701 };
1702
1703 match binding {
1704 Ok(binding) => {
1705 if segment_idx == 1 {
1706 second_binding = Some(binding);
1707 }
1708 let res = binding.res();
1709
1710 if finalize.is_some() {
1714 for error in &mut self.get_mut().privacy_errors[privacy_errors_len..] {
1715 error.outermost_res = Some((res, ident));
1716 error.source = match source {
1717 Some(PathSource::Struct(Some(expr)))
1718 | Some(PathSource::Expr(Some(expr))) => Some(expr.clone()),
1719 _ => None,
1720 };
1721 }
1722 }
1723
1724 let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(res);
1725 if let Some(def_id) = binding.res().module_like_def_id() {
1726 if self.mods_with_parse_errors.contains(&def_id) {
1727 module_had_parse_errors = true;
1728 }
1729 module = Some(ModuleOrUniformRoot::Module(self.expect_module(def_id)));
1730 record_segment_res(self.reborrow(), finalize, res, id);
1731 } else if res == Res::ToolMod && !is_last && opt_ns.is_some() {
1732 if binding.is_import() {
1733 self.dcx().emit_err(errors::ToolModuleImported {
1734 span: ident.span,
1735 import: binding.span,
1736 });
1737 }
1738 let res = Res::NonMacroAttr(NonMacroAttrKind::Tool);
1739 return PathResult::NonModule(PartialRes::new(res));
1740 } else if res == Res::Err {
1741 return PathResult::NonModule(PartialRes::new(Res::Err));
1742 } else if opt_ns.is_some() && (is_last || maybe_assoc) {
1743 if let Some(finalize) = finalize {
1744 self.get_mut().lint_if_path_starts_with_module(
1745 finalize,
1746 path,
1747 second_binding,
1748 );
1749 }
1750 record_segment_res(self.reborrow(), finalize, res, id);
1751 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1752 res,
1753 path.len() - segment_idx - 1,
1754 ));
1755 } else {
1756 return PathResult::failed(
1757 ident,
1758 is_last,
1759 finalize.is_some(),
1760 module_had_parse_errors,
1761 module,
1762 || {
1763 let label = format!(
1764 "`{ident}` is {} {}, not a module",
1765 res.article(),
1766 res.descr()
1767 );
1768 (label, None)
1769 },
1770 );
1771 }
1772 }
1773 Err(Undetermined) => return PathResult::Indeterminate,
1774 Err(Determined) => {
1775 if let Some(ModuleOrUniformRoot::Module(module)) = module
1776 && opt_ns.is_some()
1777 && !module.is_normal()
1778 {
1779 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1780 module.res().unwrap(),
1781 path.len() - segment_idx,
1782 ));
1783 }
1784
1785 let mut this = self.reborrow();
1786 return PathResult::failed(
1787 ident,
1788 is_last,
1789 finalize.is_some(),
1790 module_had_parse_errors,
1791 module,
1792 || {
1793 this.get_mut().report_path_resolution_error(
1794 path,
1795 opt_ns,
1796 parent_scope,
1797 ribs,
1798 ignore_binding,
1799 ignore_import,
1800 module,
1801 segment_idx,
1802 ident,
1803 )
1804 },
1805 );
1806 }
1807 }
1808 }
1809
1810 if let Some(finalize) = finalize {
1811 self.get_mut().lint_if_path_starts_with_module(finalize, path, second_binding);
1812 }
1813
1814 PathResult::Module(match module {
1815 Some(module) => module,
1816 None if path.is_empty() => ModuleOrUniformRoot::CurrentScope,
1817 _ => bug!("resolve_path: non-empty path `{:?}` has no module", path),
1818 })
1819 }
1820}