1use std::ops::ControlFlow;
2
3use Determinacy::*;
4use Namespace::*;
5use rustc_ast::{self as ast, NodeId};
6use rustc_errors::ErrorGuaranteed;
7use rustc_hir::def::{DefKind, MacroKinds, Namespace, NonMacroAttrKind, PartialRes, PerNS};
8use rustc_middle::{bug, span_bug};
9use rustc_session::lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK;
10use rustc_session::parse::feature_err;
11use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext};
12use rustc_span::{Ident, Span, kw, sym};
13use tracing::{debug, instrument};
14
15use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
16use crate::imports::{Import, NameResolution};
17use crate::late::{
18 ConstantHasGenerics, DiagMetadata, NoConstantGenericsReason, PathSource, Rib, RibKind,
19};
20use crate::macros::{MacroRulesScope, sub_namespace_match};
21use crate::{
22 AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingKey, CmResolver, Determinacy,
23 Finalize, ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot,
24 NameBinding, NameBindingKind, ParentScope, PathResult, PrivacyError, Res, ResolutionError,
25 Resolver, Scope, ScopeSet, Segment, Stage, Used, errors,
26};
27
28#[derive(Copy, Clone)]
29pub enum UsePrelude {
30 No,
31 Yes,
32}
33
34impl From<UsePrelude> for bool {
35 fn from(up: UsePrelude) -> bool {
36 matches!(up, UsePrelude::Yes)
37 }
38}
39
40#[derive(Debug, PartialEq, Clone, Copy)]
41enum Shadowing {
42 Restricted,
43 Unrestricted,
44}
45
46bitflags::bitflags! {
47 #[derive(Clone, Copy)]
48 struct Flags: u8 {
49 const MACRO_RULES = 1 << 0;
50 const MODULE = 1 << 1;
51 const MISC_SUGGEST_CRATE = 1 << 2;
52 const MISC_SUGGEST_SELF = 1 << 3;
53 const MISC_FROM_PRELUDE = 1 << 4;
54 }
55}
56
57impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
58 pub(crate) fn visit_scopes<'r, T>(
62 mut self: CmResolver<'r, 'ra, 'tcx>,
63 scope_set: ScopeSet<'ra>,
64 parent_scope: &ParentScope<'ra>,
65 ctxt: SyntaxContext,
66 derive_fallback_lint_id: Option<NodeId>,
67 mut visitor: impl FnMut(
68 &mut CmResolver<'r, 'ra, 'tcx>,
69 Scope<'ra>,
70 UsePrelude,
71 SyntaxContext,
72 ) -> ControlFlow<T>,
73 ) -> Option<T> {
74 let rust_2015 = ctxt.edition().is_rust_2015();
116 let (ns, macro_kind) = match scope_set {
117 ScopeSet::All(ns) | ScopeSet::ModuleAndExternPrelude(ns, _) => (ns, None),
118 ScopeSet::ExternPrelude => (TypeNS, None),
119 ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
120 };
121 let module = match scope_set {
122 ScopeSet::ModuleAndExternPrelude(_, module) => module,
124 _ => parent_scope.module.nearest_item_scope(),
126 };
127 let module_and_extern_prelude = matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..));
128 let extern_prelude = matches!(scope_set, ScopeSet::ExternPrelude);
129 let mut scope = match ns {
130 _ if module_and_extern_prelude => Scope::Module(module, None),
131 _ if extern_prelude => Scope::ExternPreludeItems,
132 TypeNS | ValueNS => Scope::Module(module, None),
133 MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
134 };
135 let mut ctxt = ctxt.normalize_to_macros_2_0();
136 let mut use_prelude = !module.no_implicit_prelude;
137
138 loop {
139 let visit = match scope {
140 Scope::DeriveHelpers(expn_id) => {
142 !(expn_id == parent_scope.expansion && macro_kind == Some(MacroKind::Derive))
143 }
144 Scope::DeriveHelpersCompat => true,
145 Scope::MacroRules(macro_rules_scope) => {
146 while let MacroRulesScope::Invocation(invoc_id) = macro_rules_scope.get() {
151 if let Some(next_scope) = self.output_macro_rules_scopes.get(&invoc_id) {
152 macro_rules_scope.set(next_scope.get());
153 } else {
154 break;
155 }
156 }
157 true
158 }
159 Scope::Module(..) => true,
160 Scope::MacroUsePrelude => use_prelude || rust_2015,
161 Scope::BuiltinAttrs => true,
162 Scope::ExternPreludeItems | Scope::ExternPreludeFlags => {
163 use_prelude || module_and_extern_prelude || extern_prelude
164 }
165 Scope::ToolPrelude => use_prelude,
166 Scope::StdLibPrelude => use_prelude || ns == MacroNS,
167 Scope::BuiltinTypes => true,
168 };
169
170 if visit {
171 let use_prelude = if use_prelude { UsePrelude::Yes } else { UsePrelude::No };
172 if let ControlFlow::Break(break_result) =
173 visitor(&mut self, scope, use_prelude, ctxt)
174 {
175 return Some(break_result);
176 }
177 }
178
179 scope = match scope {
180 Scope::DeriveHelpers(LocalExpnId::ROOT) => Scope::DeriveHelpersCompat,
181 Scope::DeriveHelpers(expn_id) => {
182 let expn_data = expn_id.expn_data();
184 match expn_data.kind {
185 ExpnKind::Root
186 | ExpnKind::Macro(MacroKind::Bang | MacroKind::Derive, _) => {
187 Scope::DeriveHelpersCompat
188 }
189 _ => Scope::DeriveHelpers(expn_data.parent.expect_local()),
190 }
191 }
192 Scope::DeriveHelpersCompat => Scope::MacroRules(parent_scope.macro_rules),
193 Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() {
194 MacroRulesScope::Binding(binding) => {
195 Scope::MacroRules(binding.parent_macro_rules_scope)
196 }
197 MacroRulesScope::Invocation(invoc_id) => {
198 Scope::MacroRules(self.invocation_parent_scopes[&invoc_id].macro_rules)
199 }
200 MacroRulesScope::Empty => Scope::Module(module, None),
201 },
202 Scope::Module(..) if module_and_extern_prelude => match ns {
203 TypeNS => {
204 ctxt.adjust(ExpnId::root());
205 Scope::ExternPreludeItems
206 }
207 ValueNS | MacroNS => break,
208 },
209 Scope::Module(module, prev_lint_id) => {
210 use_prelude = !module.no_implicit_prelude;
211 match self.hygienic_lexical_parent(module, &mut ctxt, derive_fallback_lint_id) {
212 Some((parent_module, lint_id)) => {
213 Scope::Module(parent_module, lint_id.or(prev_lint_id))
214 }
215 None => {
216 ctxt.adjust(ExpnId::root());
217 match ns {
218 TypeNS => Scope::ExternPreludeItems,
219 ValueNS => Scope::StdLibPrelude,
220 MacroNS => Scope::MacroUsePrelude,
221 }
222 }
223 }
224 }
225 Scope::MacroUsePrelude => Scope::StdLibPrelude,
226 Scope::BuiltinAttrs => break, Scope::ExternPreludeItems => Scope::ExternPreludeFlags,
228 Scope::ExternPreludeFlags if module_and_extern_prelude || extern_prelude => break,
229 Scope::ExternPreludeFlags => Scope::ToolPrelude,
230 Scope::ToolPrelude => Scope::StdLibPrelude,
231 Scope::StdLibPrelude => match ns {
232 TypeNS => Scope::BuiltinTypes,
233 ValueNS => break, MacroNS => Scope::BuiltinAttrs,
235 },
236 Scope::BuiltinTypes => break, };
238 }
239
240 None
241 }
242
243 fn hygienic_lexical_parent(
244 &self,
245 module: Module<'ra>,
246 ctxt: &mut SyntaxContext,
247 derive_fallback_lint_id: Option<NodeId>,
248 ) -> Option<(Module<'ra>, Option<NodeId>)> {
249 if !module.expansion.outer_expn_is_descendant_of(*ctxt) {
250 return Some((self.expn_def_scope(ctxt.remove_mark()), None));
251 }
252
253 if let ModuleKind::Block = module.kind {
254 return Some((module.parent.unwrap().nearest_item_scope(), None));
255 }
256
257 if derive_fallback_lint_id.is_some()
269 && let Some(parent) = module.parent
270 && module.expansion != parent.expansion
272 && module.expansion.is_descendant_of(parent.expansion)
274 && let Some(def_id) = module.expansion.expn_data().macro_def_id
276 {
277 let ext = &self.get_macro_by_def_id(def_id).ext;
278 if ext.builtin_name.is_none()
279 && ext.macro_kinds() == MacroKinds::DERIVE
280 && parent.expansion.outer_expn_is_descendant_of(*ctxt)
281 {
282 return Some((parent, derive_fallback_lint_id));
283 }
284 }
285
286 None
287 }
288
289 #[instrument(level = "debug", skip(self, ribs))]
307 pub(crate) fn resolve_ident_in_lexical_scope(
308 &mut self,
309 mut ident: Ident,
310 ns: Namespace,
311 parent_scope: &ParentScope<'ra>,
312 finalize: Option<Finalize>,
313 ribs: &[Rib<'ra>],
314 ignore_binding: Option<NameBinding<'ra>>,
315 diag_metadata: Option<&DiagMetadata<'_>>,
316 ) -> Option<LexicalScopeBinding<'ra>> {
317 let orig_ident = ident;
318 let (general_span, normalized_span) = if ident.name == kw::SelfUpper {
319 let empty_span = ident.span.with_ctxt(SyntaxContext::root());
321 (empty_span, empty_span)
322 } else if ns == TypeNS {
323 let normalized_span = ident.span.normalize_to_macros_2_0();
324 (normalized_span, normalized_span)
325 } else {
326 (ident.span.normalize_to_macro_rules(), ident.span.normalize_to_macros_2_0())
327 };
328 ident.span = general_span;
329 let normalized_ident = Ident { span: normalized_span, ..ident };
330
331 for (i, rib) in ribs.iter().enumerate().rev() {
333 debug!("walk rib\n{:?}", rib.bindings);
334 let rib_ident = if rib.kind.contains_params() { normalized_ident } else { ident };
337 if let Some((original_rib_ident_def, res)) = rib.bindings.get_key_value(&rib_ident) {
338 return Some(LexicalScopeBinding::Res(self.validate_res_from_ribs(
340 i,
341 rib_ident,
342 *res,
343 finalize.map(|_| general_span),
344 *original_rib_ident_def,
345 ribs,
346 diag_metadata,
347 )));
348 } else if let RibKind::Block(Some(module)) = rib.kind
349 && let Ok(binding) = self.cm().resolve_ident_in_module_unadjusted(
350 module,
351 ident,
352 ns,
353 parent_scope,
354 Shadowing::Unrestricted,
355 finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }),
356 ignore_binding,
357 None,
358 )
359 {
360 return Some(LexicalScopeBinding::Item(binding));
362 } else if let RibKind::Module(module) = rib.kind {
363 let parent_scope = &ParentScope { module, ..*parent_scope };
365 let finalize = finalize.map(|f| Finalize { stage: Stage::Late, ..f });
366 return self
367 .cm()
368 .resolve_ident_in_scope_set(
369 orig_ident,
370 ScopeSet::All(ns),
371 parent_scope,
372 finalize,
373 finalize.is_some(),
374 ignore_binding,
375 None,
376 )
377 .ok()
378 .map(LexicalScopeBinding::Item);
379 }
380
381 if let RibKind::MacroDefinition(def) = rib.kind
382 && def == self.macro_def(ident.span.ctxt())
383 {
384 ident.span.remove_mark();
387 }
388 }
389
390 unreachable!()
391 }
392
393 #[instrument(level = "debug", skip(self))]
395 pub(crate) fn resolve_ident_in_scope_set<'r>(
396 self: CmResolver<'r, 'ra, 'tcx>,
397 orig_ident: Ident,
398 scope_set: ScopeSet<'ra>,
399 parent_scope: &ParentScope<'ra>,
400 finalize: Option<Finalize>,
401 force: bool,
402 ignore_binding: Option<NameBinding<'ra>>,
403 ignore_import: Option<Import<'ra>>,
404 ) -> Result<NameBinding<'ra>, Determinacy> {
405 assert!(force || finalize.is_none()); if orig_ident.is_path_segment_keyword() {
409 return Err(Determinacy::Determined);
410 }
411
412 let (ns, macro_kind) = match scope_set {
413 ScopeSet::All(ns) | ScopeSet::ModuleAndExternPrelude(ns, _) => (ns, None),
414 ScopeSet::ExternPrelude => (TypeNS, None),
415 ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
416 };
417 let derive_fallback_lint_id = match finalize {
418 Some(Finalize { node_id, stage: Stage::Late, .. }) => Some(node_id),
419 _ => None,
420 };
421
422 let mut innermost_result: Option<(NameBinding<'_>, Flags)> = None;
434 let mut determinacy = Determinacy::Determined;
435 let mut extern_prelude_item_binding = None;
436 let mut extern_prelude_flag_binding = None;
437
438 let break_result = self.visit_scopes(
440 scope_set,
441 parent_scope,
442 orig_ident.span.ctxt(),
443 derive_fallback_lint_id,
444 |this, scope, use_prelude, ctxt| {
445 match this.reborrow().resolve_ident_in_scope(
449 orig_ident,
450 ns,
451 scope,
452 use_prelude,
453 ctxt,
454 scope_set,
455 parent_scope,
456 if innermost_result.is_none() { finalize } else { None },
458 force,
459 ignore_binding,
460 ignore_import,
461 &mut extern_prelude_item_binding,
462 &mut extern_prelude_flag_binding,
463 )? {
464 Ok((binding, flags))
465 if sub_namespace_match(binding.macro_kinds(), macro_kind) =>
466 {
467 if matches!(finalize, None | Some(Finalize { stage: Stage::Late, .. })) {
472 return ControlFlow::Break(Ok(binding));
473 }
474
475 if let Some((innermost_binding, innermost_flags)) = innermost_result {
476 if this.get_mut().maybe_push_ambiguity(
478 orig_ident,
479 parent_scope,
480 binding,
481 innermost_binding,
482 flags,
483 innermost_flags,
484 extern_prelude_item_binding,
485 extern_prelude_flag_binding,
486 ) {
487 return ControlFlow::Break(Ok(innermost_binding));
489 }
490 } else {
491 innermost_result = Some((binding, flags));
493 }
494 }
495 Ok(_) | Err(Determinacy::Determined) => {}
496 Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined,
497 }
498
499 ControlFlow::Continue(())
500 },
501 );
502
503 if let Some(break_result) = break_result {
505 return break_result;
506 }
507
508 match innermost_result {
510 Some((binding, _)) => Ok(binding),
511 None => Err(Determinacy::determined(determinacy == Determinacy::Determined || force)),
512 }
513 }
514
515 fn resolve_ident_in_scope<'r>(
516 mut self: CmResolver<'r, 'ra, 'tcx>,
517 orig_ident: Ident,
518 ns: Namespace,
519 scope: Scope<'ra>,
520 use_prelude: UsePrelude,
521 ctxt: SyntaxContext,
522 scope_set: ScopeSet<'ra>,
523 parent_scope: &ParentScope<'ra>,
524 finalize: Option<Finalize>,
525 force: bool,
526 ignore_binding: Option<NameBinding<'ra>>,
527 ignore_import: Option<Import<'ra>>,
528 extern_prelude_item_binding: &mut Option<NameBinding<'ra>>,
529 extern_prelude_flag_binding: &mut Option<NameBinding<'ra>>,
530 ) -> ControlFlow<
531 Result<NameBinding<'ra>, Determinacy>,
532 Result<(NameBinding<'ra>, Flags), Determinacy>,
533 > {
534 let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt));
535 let ret = match scope {
536 Scope::DeriveHelpers(expn_id) => {
537 if let Some(binding) = self.helper_attrs.get(&expn_id).and_then(|attrs| {
538 attrs.iter().rfind(|(i, _)| ident == *i).map(|(_, binding)| *binding)
539 }) {
540 Ok((binding, Flags::empty()))
541 } else {
542 Err(Determinacy::Determined)
543 }
544 }
545 Scope::DeriveHelpersCompat => {
546 let mut result = Err(Determinacy::Determined);
547 for derive in parent_scope.derives {
548 let parent_scope = &ParentScope { derives: &[], ..*parent_scope };
549 match self.reborrow().resolve_derive_macro_path(
550 derive,
551 parent_scope,
552 force,
553 ignore_import,
554 ) {
555 Ok((Some(ext), _)) => {
556 if ext.helper_attrs.contains(&ident.name) {
557 let binding = self.arenas.new_pub_res_binding(
558 Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat),
559 derive.span,
560 LocalExpnId::ROOT,
561 );
562 result = Ok((binding, Flags::empty()));
563 break;
564 }
565 }
566 Ok(_) | Err(Determinacy::Determined) => {}
567 Err(Determinacy::Undetermined) => result = Err(Determinacy::Undetermined),
568 }
569 }
570 result
571 }
572 Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() {
573 MacroRulesScope::Binding(macro_rules_binding)
574 if ident == macro_rules_binding.ident =>
575 {
576 Ok((macro_rules_binding.binding, Flags::MACRO_RULES))
577 }
578 MacroRulesScope::Invocation(_) => Err(Determinacy::Undetermined),
579 _ => Err(Determinacy::Determined),
580 },
581 Scope::Module(module, derive_fallback_lint_id) => {
582 let (adjusted_parent_scope, adjusted_finalize) =
583 if matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..)) {
584 (parent_scope, finalize)
585 } else {
586 (
587 &ParentScope { module, ..*parent_scope },
588 finalize.map(|f| Finalize { used: Used::Scope, ..f }),
589 )
590 };
591 let binding = self.reborrow().resolve_ident_in_module_unadjusted(
592 module,
593 ident,
594 ns,
595 adjusted_parent_scope,
596 Shadowing::Restricted,
597 adjusted_finalize,
598 ignore_binding,
599 ignore_import,
600 );
601 match binding {
602 Ok(binding) => {
603 if let Some(lint_id) = derive_fallback_lint_id {
604 self.get_mut().lint_buffer.buffer_lint(
605 PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
606 lint_id,
607 orig_ident.span,
608 errors::ProcMacroDeriveResolutionFallback {
609 span: orig_ident.span,
610 ns_descr: ns.descr(),
611 ident,
612 },
613 );
614 }
615 let misc_flags = if module == self.graph_root {
616 Flags::MISC_SUGGEST_CRATE
617 } else if module.is_normal() {
618 Flags::MISC_SUGGEST_SELF
619 } else {
620 Flags::empty()
621 };
622 Ok((binding, Flags::MODULE | misc_flags))
623 }
624 Err(ControlFlow::Continue(determinacy)) => Err(determinacy),
625 Err(ControlFlow::Break(Determinacy::Undetermined)) => {
626 return ControlFlow::Break(Err(Determinacy::determined(force)));
627 }
628 Err(ControlFlow::Break(Determinacy::Determined)) => unreachable!(),
630 }
631 }
632 Scope::MacroUsePrelude => match self.macro_use_prelude.get(&ident.name).cloned() {
633 Some(binding) => Ok((binding, Flags::MISC_FROM_PRELUDE)),
634 None => Err(Determinacy::determined(
635 self.graph_root.unexpanded_invocations.borrow().is_empty(),
636 )),
637 },
638 Scope::BuiltinAttrs => match self.builtin_attrs_bindings.get(&ident.name) {
639 Some(binding) => Ok((*binding, Flags::empty())),
640 None => Err(Determinacy::Determined),
641 },
642 Scope::ExternPreludeItems => {
643 match self.reborrow().extern_prelude_get_item(ident, finalize.is_some()) {
644 Some(binding) => {
645 *extern_prelude_item_binding = Some(binding);
646 Ok((binding, Flags::empty()))
647 }
648 None => Err(Determinacy::determined(
649 self.graph_root.unexpanded_invocations.borrow().is_empty(),
650 )),
651 }
652 }
653 Scope::ExternPreludeFlags => {
654 match self.extern_prelude_get_flag(ident, finalize.is_some()) {
655 Some(binding) => {
656 *extern_prelude_flag_binding = Some(binding);
657 Ok((binding, Flags::empty()))
658 }
659 None => Err(Determinacy::Determined),
660 }
661 }
662 Scope::ToolPrelude => match self.registered_tool_bindings.get(&ident) {
663 Some(binding) => Ok((*binding, Flags::empty())),
664 None => Err(Determinacy::Determined),
665 },
666 Scope::StdLibPrelude => {
667 let mut result = Err(Determinacy::Determined);
668 if let Some(prelude) = self.prelude
669 && let Ok(binding) = self.reborrow().resolve_ident_in_module_unadjusted(
670 prelude,
671 ident,
672 ns,
673 parent_scope,
674 Shadowing::Unrestricted,
675 None,
676 ignore_binding,
677 ignore_import,
678 )
679 && (matches!(use_prelude, UsePrelude::Yes)
680 || self.is_builtin_macro(binding.res()))
681 {
682 result = Ok((binding, Flags::MISC_FROM_PRELUDE));
683 }
684
685 result
686 }
687 Scope::BuiltinTypes => match self.builtin_types_bindings.get(&ident.name) {
688 Some(binding) => {
689 if matches!(ident.name, sym::f16)
690 && !self.tcx.features().f16()
691 && !ident.span.allows_unstable(sym::f16)
692 && finalize.is_some()
693 {
694 feature_err(
695 self.tcx.sess,
696 sym::f16,
697 ident.span,
698 "the type `f16` is unstable",
699 )
700 .emit();
701 }
702 if matches!(ident.name, sym::f128)
703 && !self.tcx.features().f128()
704 && !ident.span.allows_unstable(sym::f128)
705 && finalize.is_some()
706 {
707 feature_err(
708 self.tcx.sess,
709 sym::f128,
710 ident.span,
711 "the type `f128` is unstable",
712 )
713 .emit();
714 }
715 Ok((*binding, Flags::empty()))
716 }
717 None => Err(Determinacy::Determined),
718 },
719 };
720
721 ControlFlow::Continue(ret)
722 }
723
724 fn maybe_push_ambiguity(
725 &mut self,
726 orig_ident: Ident,
727 parent_scope: &ParentScope<'ra>,
728 binding: NameBinding<'ra>,
729 innermost_binding: NameBinding<'ra>,
730 flags: Flags,
731 innermost_flags: Flags,
732 extern_prelude_item_binding: Option<NameBinding<'ra>>,
733 extern_prelude_flag_binding: Option<NameBinding<'ra>>,
734 ) -> bool {
735 let (res, innermost_res) = (binding.res(), innermost_binding.res());
736 if res == innermost_res {
737 return false;
738 }
739
740 let is_builtin = |res| matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Builtin(..)));
741 let derive_helper = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
742 let derive_helper_compat = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat);
743
744 let ambiguity_error_kind = if is_builtin(innermost_res) || is_builtin(res) {
745 Some(AmbiguityKind::BuiltinAttr)
746 } else if innermost_res == derive_helper_compat
747 || res == derive_helper_compat && innermost_res != derive_helper
748 {
749 Some(AmbiguityKind::DeriveHelper)
750 } else if innermost_flags.contains(Flags::MACRO_RULES)
751 && flags.contains(Flags::MODULE)
752 && !self.disambiguate_macro_rules_vs_modularized(innermost_binding, binding)
753 {
754 Some(AmbiguityKind::MacroRulesVsModularized)
755 } else if flags.contains(Flags::MACRO_RULES) && innermost_flags.contains(Flags::MODULE) {
756 span_bug!(
762 orig_ident.span,
763 "ambiguous scoped macro resolutions with path-based \
764 scope resolution as first candidate"
765 )
766 } else if innermost_binding.is_glob_import() {
767 Some(AmbiguityKind::GlobVsOuter)
768 } else if innermost_binding.may_appear_after(parent_scope.expansion, binding) {
769 Some(AmbiguityKind::MoreExpandedVsOuter)
770 } else {
771 None
772 };
773 if let Some(kind) = ambiguity_error_kind {
774 let issue_145575_hack = Some(binding) == extern_prelude_flag_binding
778 && extern_prelude_item_binding.is_some()
779 && extern_prelude_item_binding != Some(innermost_binding);
780
781 if issue_145575_hack {
782 self.issue_145575_hack_applied = true;
783 } else {
784 let misc = |f: Flags| {
785 if f.contains(Flags::MISC_SUGGEST_CRATE) {
786 AmbiguityErrorMisc::SuggestCrate
787 } else if f.contains(Flags::MISC_SUGGEST_SELF) {
788 AmbiguityErrorMisc::SuggestSelf
789 } else if f.contains(Flags::MISC_FROM_PRELUDE) {
790 AmbiguityErrorMisc::FromPrelude
791 } else {
792 AmbiguityErrorMisc::None
793 }
794 };
795 self.ambiguity_errors.push(AmbiguityError {
796 kind,
797 ident: orig_ident,
798 b1: innermost_binding,
799 b2: binding,
800 warning: false,
801 misc1: misc(innermost_flags),
802 misc2: misc(flags),
803 });
804 return true;
805 }
806 }
807
808 false
809 }
810
811 #[instrument(level = "debug", skip(self))]
812 pub(crate) fn maybe_resolve_ident_in_module<'r>(
813 self: CmResolver<'r, 'ra, 'tcx>,
814 module: ModuleOrUniformRoot<'ra>,
815 ident: Ident,
816 ns: Namespace,
817 parent_scope: &ParentScope<'ra>,
818 ignore_import: Option<Import<'ra>>,
819 ) -> Result<NameBinding<'ra>, Determinacy> {
820 self.resolve_ident_in_module(module, ident, ns, parent_scope, None, None, ignore_import)
821 }
822
823 #[instrument(level = "debug", skip(self))]
824 pub(crate) fn resolve_ident_in_module<'r>(
825 self: CmResolver<'r, 'ra, 'tcx>,
826 module: ModuleOrUniformRoot<'ra>,
827 mut ident: Ident,
828 ns: Namespace,
829 parent_scope: &ParentScope<'ra>,
830 finalize: Option<Finalize>,
831 ignore_binding: Option<NameBinding<'ra>>,
832 ignore_import: Option<Import<'ra>>,
833 ) -> Result<NameBinding<'ra>, Determinacy> {
834 let tmp_parent_scope;
835 let mut adjusted_parent_scope = parent_scope;
836 match module {
837 ModuleOrUniformRoot::Module(m) => {
838 if let Some(def) = ident.span.normalize_to_macros_2_0_and_adjust(m.expansion) {
839 tmp_parent_scope =
840 ParentScope { module: self.expn_def_scope(def), ..*parent_scope };
841 adjusted_parent_scope = &tmp_parent_scope;
842 }
843 }
844 ModuleOrUniformRoot::ExternPrelude => {
845 ident.span.normalize_to_macros_2_0_and_adjust(ExpnId::root());
846 }
847 ModuleOrUniformRoot::ModuleAndExternPrelude(..) | ModuleOrUniformRoot::CurrentScope => {
848 }
850 }
851 self.resolve_ident_in_virt_module_unadjusted(
852 module,
853 ident,
854 ns,
855 adjusted_parent_scope,
856 finalize,
857 ignore_binding,
858 ignore_import,
859 )
860 }
861
862 #[instrument(level = "debug", skip(self))]
864 fn resolve_ident_in_virt_module_unadjusted<'r>(
865 self: CmResolver<'r, 'ra, 'tcx>,
866 module: ModuleOrUniformRoot<'ra>,
867 ident: Ident,
868 ns: Namespace,
869 parent_scope: &ParentScope<'ra>,
870 finalize: Option<Finalize>,
871 ignore_binding: Option<NameBinding<'ra>>,
872 ignore_import: Option<Import<'ra>>,
873 ) -> Result<NameBinding<'ra>, Determinacy> {
874 match module {
875 ModuleOrUniformRoot::Module(module) => self
876 .resolve_ident_in_module_unadjusted(
877 module,
878 ident,
879 ns,
880 parent_scope,
881 Shadowing::Unrestricted,
882 finalize,
883 ignore_binding,
884 ignore_import,
885 )
886 .map_err(|determinacy| determinacy.into_value()),
887 ModuleOrUniformRoot::ModuleAndExternPrelude(module) => self.resolve_ident_in_scope_set(
888 ident,
889 ScopeSet::ModuleAndExternPrelude(ns, module),
890 parent_scope,
891 finalize,
892 finalize.is_some(),
893 ignore_binding,
894 ignore_import,
895 ),
896 ModuleOrUniformRoot::ExternPrelude => {
897 if ns != TypeNS {
898 Err(Determined)
899 } else {
900 self.resolve_ident_in_scope_set(
901 ident,
902 ScopeSet::ExternPrelude,
903 parent_scope,
904 finalize,
905 finalize.is_some(),
906 ignore_binding,
907 ignore_import,
908 )
909 }
910 }
911 ModuleOrUniformRoot::CurrentScope => {
912 if ns == TypeNS {
913 if ident.name == kw::Crate || ident.name == kw::DollarCrate {
914 let module = self.resolve_crate_root(ident);
915 return Ok(module.self_binding.unwrap());
916 } else if ident.name == kw::Super || ident.name == kw::SelfLower {
917 }
921 }
922
923 self.resolve_ident_in_scope_set(
924 ident,
925 ScopeSet::All(ns),
926 parent_scope,
927 finalize,
928 finalize.is_some(),
929 ignore_binding,
930 ignore_import,
931 )
932 }
933 }
934 }
935
936 fn resolve_ident_in_module_unadjusted<'r>(
938 mut self: CmResolver<'r, 'ra, 'tcx>,
939 module: Module<'ra>,
940 ident: Ident,
941 ns: Namespace,
942 parent_scope: &ParentScope<'ra>,
943 shadowing: Shadowing,
944 finalize: Option<Finalize>,
945 ignore_binding: Option<NameBinding<'ra>>,
948 ignore_import: Option<Import<'ra>>,
949 ) -> Result<NameBinding<'ra>, ControlFlow<Determinacy, Determinacy>> {
950 let res = self.reborrow().resolve_ident_in_module_non_globs_unadjusted(
951 module,
952 ident,
953 ns,
954 parent_scope,
955 shadowing,
956 finalize,
957 ignore_binding,
958 ignore_import,
959 );
960
961 match res {
962 Ok(_) | Err(ControlFlow::Break(_)) => return res,
963 Err(ControlFlow::Continue(_)) => {}
964 }
965
966 self.resolve_ident_in_module_globs_unadjusted(
967 module,
968 ident,
969 ns,
970 parent_scope,
971 shadowing,
972 finalize,
973 ignore_binding,
974 ignore_import,
975 )
976 }
977
978 fn resolve_ident_in_module_non_globs_unadjusted<'r>(
980 mut self: CmResolver<'r, 'ra, 'tcx>,
981 module: Module<'ra>,
982 ident: Ident,
983 ns: Namespace,
984 parent_scope: &ParentScope<'ra>,
985 shadowing: Shadowing,
986 finalize: Option<Finalize>,
987 ignore_binding: Option<NameBinding<'ra>>,
988 ignore_import: Option<Import<'ra>>,
989 ) -> Result<NameBinding<'ra>, ControlFlow<Determinacy, Determinacy>> {
990 let key = BindingKey::new(ident, ns);
991 let resolution = &*self
995 .resolution_or_default(module, key)
996 .try_borrow_mut_unchecked()
997 .map_err(|_| ControlFlow::Continue(Determined))?;
998
999 let binding = resolution.non_glob_binding.filter(|b| Some(*b) != ignore_binding);
1000
1001 if let Some(finalize) = finalize {
1002 return self.get_mut().finalize_module_binding(
1003 ident,
1004 binding,
1005 if resolution.non_glob_binding.is_some() { resolution.glob_binding } else { None },
1006 parent_scope,
1007 module,
1008 finalize,
1009 shadowing,
1010 );
1011 }
1012
1013 if let Some(binding) = binding {
1015 let accessible = self.is_accessible_from(binding.vis, parent_scope.module);
1016 return if accessible { Ok(binding) } else { Err(ControlFlow::Break(Determined)) };
1017 }
1018
1019 if self.reborrow().single_import_can_define_name(
1021 &resolution,
1022 None,
1023 ns,
1024 ignore_import,
1025 ignore_binding,
1026 parent_scope,
1027 ) {
1028 return Err(ControlFlow::Break(Undetermined));
1029 }
1030
1031 if !module.unexpanded_invocations.borrow().is_empty() {
1033 return Err(ControlFlow::Continue(Undetermined));
1034 }
1035
1036 Err(ControlFlow::Continue(Determined))
1038 }
1039
1040 fn resolve_ident_in_module_globs_unadjusted<'r>(
1042 mut self: CmResolver<'r, 'ra, 'tcx>,
1043 module: Module<'ra>,
1044 ident: Ident,
1045 ns: Namespace,
1046 parent_scope: &ParentScope<'ra>,
1047 shadowing: Shadowing,
1048 finalize: Option<Finalize>,
1049 ignore_binding: Option<NameBinding<'ra>>,
1050 ignore_import: Option<Import<'ra>>,
1051 ) -> Result<NameBinding<'ra>, ControlFlow<Determinacy, Determinacy>> {
1052 let key = BindingKey::new(ident, ns);
1053 let resolution = &*self
1057 .resolution_or_default(module, key)
1058 .try_borrow_mut_unchecked()
1059 .map_err(|_| ControlFlow::Continue(Determined))?;
1060
1061 let binding = resolution.glob_binding.filter(|b| Some(*b) != ignore_binding);
1062
1063 if let Some(finalize) = finalize {
1064 return self.get_mut().finalize_module_binding(
1065 ident,
1066 binding,
1067 if resolution.non_glob_binding.is_some() { resolution.glob_binding } else { None },
1068 parent_scope,
1069 module,
1070 finalize,
1071 shadowing,
1072 );
1073 }
1074
1075 if self.reborrow().single_import_can_define_name(
1078 &resolution,
1079 binding,
1080 ns,
1081 ignore_import,
1082 ignore_binding,
1083 parent_scope,
1084 ) {
1085 return Err(ControlFlow::Break(Undetermined));
1086 }
1087
1088 if let Some(binding) = binding {
1101 return if binding.determined() || ns == MacroNS || shadowing == Shadowing::Restricted {
1102 let accessible = self.is_accessible_from(binding.vis, parent_scope.module);
1103 if accessible { Ok(binding) } else { Err(ControlFlow::Break(Determined)) }
1104 } else {
1105 Err(ControlFlow::Break(Undetermined))
1106 };
1107 }
1108
1109 if !module.unexpanded_invocations.borrow().is_empty() {
1117 return Err(ControlFlow::Continue(Undetermined));
1118 }
1119
1120 for glob_import in module.globs.borrow().iter() {
1123 if ignore_import == Some(*glob_import) {
1124 continue;
1125 }
1126 if !self.is_accessible_from(glob_import.vis, parent_scope.module) {
1127 continue;
1128 }
1129 let module = match glob_import.imported_module.get() {
1130 Some(ModuleOrUniformRoot::Module(module)) => module,
1131 Some(_) => continue,
1132 None => return Err(ControlFlow::Continue(Undetermined)),
1133 };
1134 let tmp_parent_scope;
1135 let (mut adjusted_parent_scope, mut ident) =
1136 (parent_scope, ident.normalize_to_macros_2_0());
1137 match ident.span.glob_adjust(module.expansion, glob_import.span) {
1138 Some(Some(def)) => {
1139 tmp_parent_scope =
1140 ParentScope { module: self.expn_def_scope(def), ..*parent_scope };
1141 adjusted_parent_scope = &tmp_parent_scope;
1142 }
1143 Some(None) => {}
1144 None => continue,
1145 };
1146 let result = self.reborrow().resolve_ident_in_module_unadjusted(
1147 module,
1148 ident,
1149 ns,
1150 adjusted_parent_scope,
1151 Shadowing::Unrestricted,
1152 None,
1153 ignore_binding,
1154 ignore_import,
1155 );
1156
1157 match result {
1158 Err(ControlFlow::Break(Determined) | ControlFlow::Continue(Determined)) => continue,
1159 Ok(binding)
1160 if !self.is_accessible_from(binding.vis, glob_import.parent_scope.module) =>
1161 {
1162 continue;
1163 }
1164 Ok(_)
1165 | Err(ControlFlow::Break(Undetermined) | ControlFlow::Continue(Undetermined)) => {
1166 return Err(ControlFlow::Continue(Undetermined));
1167 }
1168 }
1169 }
1170
1171 Err(ControlFlow::Continue(Determined))
1173 }
1174
1175 fn finalize_module_binding(
1176 &mut self,
1177 ident: Ident,
1178 binding: Option<NameBinding<'ra>>,
1179 shadowed_glob: Option<NameBinding<'ra>>,
1180 parent_scope: &ParentScope<'ra>,
1181 module: Module<'ra>,
1182 finalize: Finalize,
1183 shadowing: Shadowing,
1184 ) -> Result<NameBinding<'ra>, ControlFlow<Determinacy, Determinacy>> {
1185 let Finalize { path_span, report_private, used, root_span, .. } = finalize;
1186
1187 let Some(binding) = binding else {
1188 return Err(ControlFlow::Continue(Determined));
1189 };
1190
1191 if !self.is_accessible_from(binding.vis, parent_scope.module) {
1192 if report_private {
1193 self.privacy_errors.push(PrivacyError {
1194 ident,
1195 binding,
1196 dedup_span: path_span,
1197 outermost_res: None,
1198 source: None,
1199 parent_scope: *parent_scope,
1200 single_nested: path_span != root_span,
1201 });
1202 } else {
1203 return Err(ControlFlow::Break(Determined));
1204 }
1205 }
1206
1207 if let Some(shadowed_glob) = shadowed_glob
1209 && shadowing == Shadowing::Restricted
1210 && finalize.stage == Stage::Early
1211 && binding.expansion != LocalExpnId::ROOT
1212 && binding.res() != shadowed_glob.res()
1213 {
1214 self.ambiguity_errors.push(AmbiguityError {
1215 kind: AmbiguityKind::GlobVsExpanded,
1216 ident,
1217 b1: binding,
1218 b2: shadowed_glob,
1219 warning: false,
1220 misc1: AmbiguityErrorMisc::None,
1221 misc2: AmbiguityErrorMisc::None,
1222 });
1223 }
1224
1225 if shadowing == Shadowing::Unrestricted
1226 && binding.expansion != LocalExpnId::ROOT
1227 && let NameBindingKind::Import { import, .. } = binding.kind
1228 && matches!(import.kind, ImportKind::MacroExport)
1229 {
1230 self.macro_expanded_macro_export_errors.insert((path_span, binding.span));
1231 }
1232
1233 if let Res::Def(_, def_id) = binding.res() {
1237 let struct_ctor = match def_id.as_local() {
1238 Some(def_id) => self.struct_constructors.get(&def_id).cloned(),
1239 None => {
1240 let ctor = self.cstore().ctor_untracked(self.tcx(), def_id);
1241 ctor.map(|(ctor_kind, ctor_def_id)| {
1242 let ctor_res = Res::Def(
1243 DefKind::Ctor(rustc_hir::def::CtorOf::Struct, ctor_kind),
1244 ctor_def_id,
1245 );
1246 let ctor_vis = self.tcx.visibility(ctor_def_id);
1247 let field_visibilities = self
1248 .tcx
1249 .associated_item_def_ids(def_id)
1250 .iter()
1251 .map(|field_id| self.tcx.visibility(field_id))
1252 .collect();
1253 (ctor_res, ctor_vis, field_visibilities)
1254 })
1255 }
1256 };
1257 if let Some((_, _, fields)) = struct_ctor
1258 && fields.iter().any(|vis| !self.is_accessible_from(*vis, module))
1259 {
1260 self.inaccessible_ctor_reexport.insert(path_span, binding.span);
1261 }
1262 }
1263
1264 self.record_use(ident, binding, used);
1265 return Ok(binding);
1266 }
1267
1268 fn single_import_can_define_name<'r>(
1271 mut self: CmResolver<'r, 'ra, 'tcx>,
1272 resolution: &NameResolution<'ra>,
1273 binding: Option<NameBinding<'ra>>,
1274 ns: Namespace,
1275 ignore_import: Option<Import<'ra>>,
1276 ignore_binding: Option<NameBinding<'ra>>,
1277 parent_scope: &ParentScope<'ra>,
1278 ) -> bool {
1279 for single_import in &resolution.single_imports {
1280 if ignore_import == Some(*single_import) {
1281 continue;
1282 }
1283 if !self.is_accessible_from(single_import.vis, parent_scope.module) {
1284 continue;
1285 }
1286 if let Some(ignored) = ignore_binding
1287 && let NameBindingKind::Import { import, .. } = ignored.kind
1288 && import == *single_import
1289 {
1290 continue;
1291 }
1292
1293 let Some(module) = single_import.imported_module.get() else {
1294 return true;
1295 };
1296 let ImportKind::Single { source, target, bindings, .. } = &single_import.kind else {
1297 unreachable!();
1298 };
1299 if source != target {
1300 if bindings.iter().all(|binding| binding.get().binding().is_none()) {
1301 return true;
1302 } else if bindings[ns].get().binding().is_none() && binding.is_some() {
1303 return true;
1304 }
1305 }
1306
1307 match self.reborrow().resolve_ident_in_module(
1308 module,
1309 *source,
1310 ns,
1311 &single_import.parent_scope,
1312 None,
1313 ignore_binding,
1314 ignore_import,
1315 ) {
1316 Err(Determined) => continue,
1317 Ok(binding)
1318 if !self.is_accessible_from(binding.vis, single_import.parent_scope.module) =>
1319 {
1320 continue;
1321 }
1322 Ok(_) | Err(Undetermined) => return true,
1323 }
1324 }
1325
1326 false
1327 }
1328
1329 #[instrument(level = "debug", skip(self, all_ribs))]
1331 fn validate_res_from_ribs(
1332 &mut self,
1333 rib_index: usize,
1334 rib_ident: Ident,
1335 mut res: Res,
1336 finalize: Option<Span>,
1337 original_rib_ident_def: Ident,
1338 all_ribs: &[Rib<'ra>],
1339 diag_metadata: Option<&DiagMetadata<'_>>,
1340 ) -> Res {
1341 debug!("validate_res_from_ribs({:?})", res);
1342 let ribs = &all_ribs[rib_index + 1..];
1343
1344 if let RibKind::ForwardGenericParamBan(reason) = all_ribs[rib_index].kind {
1347 if let Some(span) = finalize {
1348 let res_error = if rib_ident.name == kw::SelfUpper {
1349 ResolutionError::ForwardDeclaredSelf(reason)
1350 } else {
1351 ResolutionError::ForwardDeclaredGenericParam(rib_ident.name, reason)
1352 };
1353 self.report_error(span, res_error);
1354 }
1355 assert_eq!(res, Res::Err);
1356 return Res::Err;
1357 }
1358
1359 match res {
1360 Res::Local(_) => {
1361 use ResolutionError::*;
1362 let mut res_err = None;
1363
1364 for rib in ribs {
1365 match rib.kind {
1366 RibKind::Normal
1367 | RibKind::Block(..)
1368 | RibKind::FnOrCoroutine
1369 | RibKind::Module(..)
1370 | RibKind::MacroDefinition(..)
1371 | RibKind::ForwardGenericParamBan(_) => {
1372 }
1374 RibKind::Item(..) | RibKind::AssocItem => {
1375 if let Some(span) = finalize {
1379 res_err = Some((span, CannotCaptureDynamicEnvironmentInFnItem));
1384 }
1385 }
1386 RibKind::ConstantItem(_, item) => {
1387 if let Some(span) = finalize {
1389 let (span, resolution_error) = match item {
1390 None if rib_ident.name == kw::SelfLower => {
1391 (span, LowercaseSelf)
1392 }
1393 None => {
1394 let sm = self.tcx.sess.source_map();
1400 let type_span = match sm.span_look_ahead(
1401 original_rib_ident_def.span,
1402 ":",
1403 None,
1404 ) {
1405 None => {
1406 Some(original_rib_ident_def.span.shrink_to_hi())
1407 }
1408 Some(_) => None,
1409 };
1410 (
1411 rib_ident.span,
1412 AttemptToUseNonConstantValueInConstant {
1413 ident: original_rib_ident_def,
1414 suggestion: "const",
1415 current: "let",
1416 type_span,
1417 },
1418 )
1419 }
1420 Some((ident, kind)) => (
1421 span,
1422 AttemptToUseNonConstantValueInConstant {
1423 ident,
1424 suggestion: "let",
1425 current: kind.as_str(),
1426 type_span: None,
1427 },
1428 ),
1429 };
1430 self.report_error(span, resolution_error);
1431 }
1432 return Res::Err;
1433 }
1434 RibKind::ConstParamTy => {
1435 if let Some(span) = finalize {
1436 self.report_error(
1437 span,
1438 ParamInTyOfConstParam { name: rib_ident.name },
1439 );
1440 }
1441 return Res::Err;
1442 }
1443 RibKind::InlineAsmSym => {
1444 if let Some(span) = finalize {
1445 self.report_error(span, InvalidAsmSym);
1446 }
1447 return Res::Err;
1448 }
1449 }
1450 }
1451 if let Some((span, res_err)) = res_err {
1452 self.report_error(span, res_err);
1453 return Res::Err;
1454 }
1455 }
1456 Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {
1457 for rib in ribs {
1458 let (has_generic_params, def_kind) = match rib.kind {
1459 RibKind::Normal
1460 | RibKind::Block(..)
1461 | RibKind::FnOrCoroutine
1462 | RibKind::Module(..)
1463 | RibKind::MacroDefinition(..)
1464 | RibKind::InlineAsmSym
1465 | RibKind::AssocItem
1466 | RibKind::ForwardGenericParamBan(_) => {
1467 continue;
1469 }
1470
1471 RibKind::ConstParamTy => {
1472 if !self.tcx.features().generic_const_parameter_types() {
1473 if let Some(span) = finalize {
1474 self.report_error(
1475 span,
1476 ResolutionError::ParamInTyOfConstParam {
1477 name: rib_ident.name,
1478 },
1479 );
1480 }
1481 return Res::Err;
1482 } else {
1483 continue;
1484 }
1485 }
1486
1487 RibKind::ConstantItem(trivial, _) => {
1488 if let ConstantHasGenerics::No(cause) = trivial {
1489 if let Res::SelfTyAlias {
1494 alias_to: def,
1495 forbid_generic: _,
1496 is_trait_impl,
1497 } = res
1498 {
1499 res = Res::SelfTyAlias {
1500 alias_to: def,
1501 forbid_generic: true,
1502 is_trait_impl,
1503 }
1504 } else {
1505 if let Some(span) = finalize {
1506 let error = match cause {
1507 NoConstantGenericsReason::IsEnumDiscriminant => {
1508 ResolutionError::ParamInEnumDiscriminant {
1509 name: rib_ident.name,
1510 param_kind: ParamKindInEnumDiscriminant::Type,
1511 }
1512 }
1513 NoConstantGenericsReason::NonTrivialConstArg => {
1514 ResolutionError::ParamInNonTrivialAnonConst {
1515 name: rib_ident.name,
1516 param_kind:
1517 ParamKindInNonTrivialAnonConst::Type,
1518 }
1519 }
1520 };
1521 let _: ErrorGuaranteed = self.report_error(span, error);
1522 }
1523
1524 return Res::Err;
1525 }
1526 }
1527
1528 continue;
1529 }
1530
1531 RibKind::Item(has_generic_params, def_kind) => {
1533 (has_generic_params, def_kind)
1534 }
1535 };
1536
1537 if let Some(span) = finalize {
1538 let item = if let Some(diag_metadata) = diag_metadata
1539 && let Some(current_item) = diag_metadata.current_item
1540 {
1541 let span = current_item
1542 .kind
1543 .ident()
1544 .map(|i| i.span)
1545 .unwrap_or(current_item.span);
1546 Some((span, current_item.kind.clone()))
1547 } else {
1548 None
1549 };
1550 self.report_error(
1551 span,
1552 ResolutionError::GenericParamsFromOuterItem {
1553 outer_res: res,
1554 has_generic_params,
1555 def_kind,
1556 inner_item: item,
1557 current_self_ty: diag_metadata
1558 .and_then(|m| m.current_self_type.as_ref())
1559 .and_then(|ty| {
1560 self.tcx.sess.source_map().span_to_snippet(ty.span).ok()
1561 }),
1562 },
1563 );
1564 }
1565 return Res::Err;
1566 }
1567 }
1568 Res::Def(DefKind::ConstParam, _) => {
1569 for rib in ribs {
1570 let (has_generic_params, def_kind) = match rib.kind {
1571 RibKind::Normal
1572 | RibKind::Block(..)
1573 | RibKind::FnOrCoroutine
1574 | RibKind::Module(..)
1575 | RibKind::MacroDefinition(..)
1576 | RibKind::InlineAsmSym
1577 | RibKind::AssocItem
1578 | RibKind::ForwardGenericParamBan(_) => continue,
1579
1580 RibKind::ConstParamTy => {
1581 if !self.tcx.features().generic_const_parameter_types() {
1582 if let Some(span) = finalize {
1583 self.report_error(
1584 span,
1585 ResolutionError::ParamInTyOfConstParam {
1586 name: rib_ident.name,
1587 },
1588 );
1589 }
1590 return Res::Err;
1591 } else {
1592 continue;
1593 }
1594 }
1595
1596 RibKind::ConstantItem(trivial, _) => {
1597 if let ConstantHasGenerics::No(cause) = trivial {
1598 if let Some(span) = finalize {
1599 let error = match cause {
1600 NoConstantGenericsReason::IsEnumDiscriminant => {
1601 ResolutionError::ParamInEnumDiscriminant {
1602 name: rib_ident.name,
1603 param_kind: ParamKindInEnumDiscriminant::Const,
1604 }
1605 }
1606 NoConstantGenericsReason::NonTrivialConstArg => {
1607 ResolutionError::ParamInNonTrivialAnonConst {
1608 name: rib_ident.name,
1609 param_kind: ParamKindInNonTrivialAnonConst::Const {
1610 name: rib_ident.name,
1611 },
1612 }
1613 }
1614 };
1615 self.report_error(span, error);
1616 }
1617
1618 return Res::Err;
1619 }
1620
1621 continue;
1622 }
1623
1624 RibKind::Item(has_generic_params, def_kind) => {
1625 (has_generic_params, def_kind)
1626 }
1627 };
1628
1629 if let Some(span) = finalize {
1631 let item = if let Some(diag_metadata) = diag_metadata
1632 && let Some(current_item) = diag_metadata.current_item
1633 {
1634 let span = current_item
1635 .kind
1636 .ident()
1637 .map(|i| i.span)
1638 .unwrap_or(current_item.span);
1639 Some((span, current_item.kind.clone()))
1640 } else {
1641 None
1642 };
1643 self.report_error(
1644 span,
1645 ResolutionError::GenericParamsFromOuterItem {
1646 outer_res: res,
1647 has_generic_params,
1648 def_kind,
1649 inner_item: item,
1650 current_self_ty: diag_metadata
1651 .and_then(|m| m.current_self_type.as_ref())
1652 .and_then(|ty| {
1653 self.tcx.sess.source_map().span_to_snippet(ty.span).ok()
1654 }),
1655 },
1656 );
1657 }
1658 return Res::Err;
1659 }
1660 }
1661 _ => {}
1662 }
1663
1664 res
1665 }
1666
1667 #[instrument(level = "debug", skip(self))]
1668 pub(crate) fn maybe_resolve_path<'r>(
1669 self: CmResolver<'r, 'ra, 'tcx>,
1670 path: &[Segment],
1671 opt_ns: Option<Namespace>, parent_scope: &ParentScope<'ra>,
1673 ignore_import: Option<Import<'ra>>,
1674 ) -> PathResult<'ra> {
1675 self.resolve_path_with_ribs(
1676 path,
1677 opt_ns,
1678 parent_scope,
1679 None,
1680 None,
1681 None,
1682 None,
1683 ignore_import,
1684 None,
1685 )
1686 }
1687 #[instrument(level = "debug", skip(self))]
1688 pub(crate) fn resolve_path<'r>(
1689 self: CmResolver<'r, 'ra, 'tcx>,
1690 path: &[Segment],
1691 opt_ns: Option<Namespace>, parent_scope: &ParentScope<'ra>,
1693 finalize: Option<Finalize>,
1694 ignore_binding: Option<NameBinding<'ra>>,
1695 ignore_import: Option<Import<'ra>>,
1696 ) -> PathResult<'ra> {
1697 self.resolve_path_with_ribs(
1698 path,
1699 opt_ns,
1700 parent_scope,
1701 None,
1702 finalize,
1703 None,
1704 ignore_binding,
1705 ignore_import,
1706 None,
1707 )
1708 }
1709
1710 pub(crate) fn resolve_path_with_ribs<'r>(
1711 mut self: CmResolver<'r, 'ra, 'tcx>,
1712 path: &[Segment],
1713 opt_ns: Option<Namespace>, parent_scope: &ParentScope<'ra>,
1715 source: Option<PathSource<'_, '_, '_>>,
1716 finalize: Option<Finalize>,
1717 ribs: Option<&PerNS<Vec<Rib<'ra>>>>,
1718 ignore_binding: Option<NameBinding<'ra>>,
1719 ignore_import: Option<Import<'ra>>,
1720 diag_metadata: Option<&DiagMetadata<'_>>,
1721 ) -> PathResult<'ra> {
1722 let mut module = None;
1723 let mut module_had_parse_errors = false;
1724 let mut allow_super = true;
1725 let mut second_binding = None;
1726
1727 let privacy_errors_len = self.privacy_errors.len();
1729 fn record_segment_res<'r, 'ra, 'tcx>(
1730 mut this: CmResolver<'r, 'ra, 'tcx>,
1731 finalize: Option<Finalize>,
1732 res: Res,
1733 id: Option<NodeId>,
1734 ) {
1735 if finalize.is_some()
1736 && let Some(id) = id
1737 && !this.partial_res_map.contains_key(&id)
1738 {
1739 assert!(id != ast::DUMMY_NODE_ID, "Trying to resolve dummy id");
1740 this.get_mut().record_partial_res(id, PartialRes::new(res));
1741 }
1742 }
1743
1744 for (segment_idx, &Segment { ident, id, .. }) in path.iter().enumerate() {
1745 debug!("resolve_path ident {} {:?} {:?}", segment_idx, ident, id);
1746
1747 let is_last = segment_idx + 1 == path.len();
1748 let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };
1749 let name = ident.name;
1750
1751 allow_super &= ns == TypeNS && (name == kw::SelfLower || name == kw::Super);
1752
1753 if ns == TypeNS {
1754 if allow_super && name == kw::Super {
1755 let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();
1756 let self_module = match segment_idx {
1757 0 => Some(self.resolve_self(&mut ctxt, parent_scope.module)),
1758 _ => match module {
1759 Some(ModuleOrUniformRoot::Module(module)) => Some(module),
1760 _ => None,
1761 },
1762 };
1763 if let Some(self_module) = self_module
1764 && let Some(parent) = self_module.parent
1765 {
1766 module =
1767 Some(ModuleOrUniformRoot::Module(self.resolve_self(&mut ctxt, parent)));
1768 continue;
1769 }
1770 return PathResult::failed(
1771 ident,
1772 false,
1773 finalize.is_some(),
1774 module_had_parse_errors,
1775 module,
1776 || ("there are too many leading `super` keywords".to_string(), None),
1777 );
1778 }
1779 if segment_idx == 0 {
1780 if name == kw::SelfLower {
1781 let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();
1782 let self_mod = self.resolve_self(&mut ctxt, parent_scope.module);
1783 if let Some(res) = self_mod.res() {
1784 record_segment_res(self.reborrow(), finalize, res, id);
1785 }
1786 module = Some(ModuleOrUniformRoot::Module(self_mod));
1787 continue;
1788 }
1789 if name == kw::PathRoot && ident.span.at_least_rust_2018() {
1790 module = Some(ModuleOrUniformRoot::ExternPrelude);
1791 continue;
1792 }
1793 if name == kw::PathRoot
1794 && ident.span.is_rust_2015()
1795 && self.tcx.sess.at_least_rust_2018()
1796 {
1797 let crate_root = self.resolve_crate_root(ident);
1799 module = Some(ModuleOrUniformRoot::ModuleAndExternPrelude(crate_root));
1800 continue;
1801 }
1802 if name == kw::PathRoot || name == kw::Crate || name == kw::DollarCrate {
1803 let crate_root = self.resolve_crate_root(ident);
1805 if let Some(res) = crate_root.res() {
1806 record_segment_res(self.reborrow(), finalize, res, id);
1807 }
1808 module = Some(ModuleOrUniformRoot::Module(crate_root));
1809 continue;
1810 }
1811 }
1812 }
1813
1814 if ident.is_path_segment_keyword() && segment_idx != 0 {
1816 return PathResult::failed(
1817 ident,
1818 false,
1819 finalize.is_some(),
1820 module_had_parse_errors,
1821 module,
1822 || {
1823 let name_str = if name == kw::PathRoot {
1824 "crate root".to_string()
1825 } else {
1826 format!("`{name}`")
1827 };
1828 let label = if segment_idx == 1 && path[0].ident.name == kw::PathRoot {
1829 format!("global paths cannot start with {name_str}")
1830 } else {
1831 format!("{name_str} in paths can only be used in start position")
1832 };
1833 (label, None)
1834 },
1835 );
1836 }
1837
1838 let binding = if let Some(module) = module {
1839 self.reborrow().resolve_ident_in_module(
1840 module,
1841 ident,
1842 ns,
1843 parent_scope,
1844 finalize,
1845 ignore_binding,
1846 ignore_import,
1847 )
1848 } else if let Some(ribs) = ribs
1849 && let Some(TypeNS | ValueNS) = opt_ns
1850 {
1851 assert!(ignore_import.is_none());
1852 match self.get_mut().resolve_ident_in_lexical_scope(
1853 ident,
1854 ns,
1855 parent_scope,
1856 finalize,
1857 &ribs[ns],
1858 ignore_binding,
1859 diag_metadata,
1860 ) {
1861 Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
1863 Some(LexicalScopeBinding::Res(res)) => {
1865 record_segment_res(self.reborrow(), finalize, res, id);
1866 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1867 res,
1868 path.len() - 1,
1869 ));
1870 }
1871 _ => Err(Determinacy::determined(finalize.is_some())),
1872 }
1873 } else {
1874 self.reborrow().resolve_ident_in_scope_set(
1875 ident,
1876 ScopeSet::All(ns),
1877 parent_scope,
1878 finalize,
1879 finalize.is_some(),
1880 ignore_binding,
1881 ignore_import,
1882 )
1883 };
1884
1885 match binding {
1886 Ok(binding) => {
1887 if segment_idx == 1 {
1888 second_binding = Some(binding);
1889 }
1890 let res = binding.res();
1891
1892 if finalize.is_some() {
1896 for error in &mut self.get_mut().privacy_errors[privacy_errors_len..] {
1897 error.outermost_res = Some((res, ident));
1898 error.source = match source {
1899 Some(PathSource::Struct(Some(expr)))
1900 | Some(PathSource::Expr(Some(expr))) => Some(expr.clone()),
1901 _ => None,
1902 };
1903 }
1904 }
1905
1906 let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(res);
1907 if let Some(def_id) = binding.res().module_like_def_id() {
1908 if self.mods_with_parse_errors.contains(&def_id) {
1909 module_had_parse_errors = true;
1910 }
1911 module = Some(ModuleOrUniformRoot::Module(self.expect_module(def_id)));
1912 record_segment_res(self.reborrow(), finalize, res, id);
1913 } else if res == Res::ToolMod && !is_last && opt_ns.is_some() {
1914 if binding.is_import() {
1915 self.dcx().emit_err(errors::ToolModuleImported {
1916 span: ident.span,
1917 import: binding.span,
1918 });
1919 }
1920 let res = Res::NonMacroAttr(NonMacroAttrKind::Tool);
1921 return PathResult::NonModule(PartialRes::new(res));
1922 } else if res == Res::Err {
1923 return PathResult::NonModule(PartialRes::new(Res::Err));
1924 } else if opt_ns.is_some() && (is_last || maybe_assoc) {
1925 if let Some(finalize) = finalize {
1926 self.get_mut().lint_if_path_starts_with_module(
1927 finalize,
1928 path,
1929 second_binding,
1930 );
1931 }
1932 record_segment_res(self.reborrow(), finalize, res, id);
1933 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1934 res,
1935 path.len() - segment_idx - 1,
1936 ));
1937 } else {
1938 return PathResult::failed(
1939 ident,
1940 is_last,
1941 finalize.is_some(),
1942 module_had_parse_errors,
1943 module,
1944 || {
1945 let label = format!(
1946 "`{ident}` is {} {}, not a module",
1947 res.article(),
1948 res.descr()
1949 );
1950 (label, None)
1951 },
1952 );
1953 }
1954 }
1955 Err(Undetermined) => return PathResult::Indeterminate,
1956 Err(Determined) => {
1957 if let Some(ModuleOrUniformRoot::Module(module)) = module
1958 && opt_ns.is_some()
1959 && !module.is_normal()
1960 {
1961 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1962 module.res().unwrap(),
1963 path.len() - segment_idx,
1964 ));
1965 }
1966
1967 let mut this = self.reborrow();
1968 return PathResult::failed(
1969 ident,
1970 is_last,
1971 finalize.is_some(),
1972 module_had_parse_errors,
1973 module,
1974 || {
1975 this.get_mut().report_path_resolution_error(
1976 path,
1977 opt_ns,
1978 parent_scope,
1979 ribs,
1980 ignore_binding,
1981 ignore_import,
1982 module,
1983 segment_idx,
1984 ident,
1985 diag_metadata,
1986 )
1987 },
1988 );
1989 }
1990 }
1991 }
1992
1993 if let Some(finalize) = finalize {
1994 self.get_mut().lint_if_path_starts_with_module(finalize, path, second_binding);
1995 }
1996
1997 PathResult::Module(match module {
1998 Some(module) => module,
1999 None if path.is_empty() => ModuleOrUniformRoot::CurrentScope,
2000 _ => bug!("resolve_path: non-empty path `{:?}` has no module", path),
2001 })
2002 }
2003}