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