1use Determinacy::*;
2use Namespace::*;
3use rustc_ast::{self as ast, NodeId};
4use rustc_errors::ErrorGuaranteed;
5use rustc_hir::def::{DefKind, Namespace, NonMacroAttrKind, PartialRes, PerNS};
6use rustc_middle::bug;
7use rustc_session::lint::BuiltinLintDiag;
8use rustc_session::lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK;
9use rustc_session::parse::feature_err;
10use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext};
11use rustc_span::{Ident, Span, kw, sym};
12use tracing::{debug, instrument};
13
14use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
15use crate::imports::{Import, NameResolution};
16use crate::late::{ConstantHasGenerics, NoConstantGenericsReason, PathSource, Rib, RibKind};
17use crate::macros::{MacroRulesScope, sub_namespace_match};
18use crate::{
19 AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingKey, Determinacy, Finalize,
20 ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot, NameBinding,
21 NameBindingKind, ParentScope, PathResult, PrivacyError, Res, ResolutionError, Resolver, Scope,
22 ScopeSet, Segment, Used, Weak, errors,
23};
24
25#[derive(Copy, Clone)]
26pub enum UsePrelude {
27 No,
28 Yes,
29}
30
31impl From<UsePrelude> for bool {
32 fn from(up: UsePrelude) -> bool {
33 matches!(up, UsePrelude::Yes)
34 }
35}
36
37#[derive(Debug, PartialEq, Clone, Copy)]
38enum Shadowing {
39 Restricted,
40 Unrestricted,
41}
42
43impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
44 pub(crate) fn visit_scopes<T>(
48 &mut self,
49 scope_set: ScopeSet<'ra>,
50 parent_scope: &ParentScope<'ra>,
51 ctxt: SyntaxContext,
52 mut visitor: impl FnMut(&mut Self, Scope<'ra>, UsePrelude, SyntaxContext) -> Option<T>,
53 ) -> Option<T> {
54 let rust_2015 = ctxt.edition().is_rust_2015();
96 let (ns, macro_kind) = match scope_set {
97 ScopeSet::All(ns)
98 | ScopeSet::ModuleAndExternPrelude(ns, _)
99 | ScopeSet::Late(ns, ..) => (ns, None),
100 ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
101 };
102 let module = match scope_set {
103 ScopeSet::Late(_, module, _) | ScopeSet::ModuleAndExternPrelude(_, module) => module,
105 _ => parent_scope.module.nearest_item_scope(),
107 };
108 let module_and_extern_prelude = matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..));
109 let mut scope = match ns {
110 _ if module_and_extern_prelude => Scope::Module(module, None),
111 TypeNS | ValueNS => Scope::Module(module, None),
112 MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
113 };
114 let mut ctxt = ctxt.normalize_to_macros_2_0();
115 let mut use_prelude = !module.no_implicit_prelude;
116
117 loop {
118 let visit = match scope {
119 Scope::DeriveHelpers(expn_id) => {
121 !(expn_id == parent_scope.expansion && macro_kind == Some(MacroKind::Derive))
122 }
123 Scope::DeriveHelpersCompat => true,
124 Scope::MacroRules(macro_rules_scope) => {
125 while let MacroRulesScope::Invocation(invoc_id) = macro_rules_scope.get() {
130 if let Some(next_scope) = self.output_macro_rules_scopes.get(&invoc_id) {
131 macro_rules_scope.set(next_scope.get());
132 } else {
133 break;
134 }
135 }
136 true
137 }
138 Scope::Module(..) => true,
139 Scope::MacroUsePrelude => use_prelude || rust_2015,
140 Scope::BuiltinAttrs => true,
141 Scope::ExternPrelude => use_prelude || module_and_extern_prelude,
142 Scope::ToolPrelude => use_prelude,
143 Scope::StdLibPrelude => use_prelude || ns == MacroNS,
144 Scope::BuiltinTypes => true,
145 };
146
147 if visit {
148 let use_prelude = if use_prelude { UsePrelude::Yes } else { UsePrelude::No };
149 if let break_result @ Some(..) = visitor(self, scope, use_prelude, ctxt) {
150 return break_result;
151 }
152 }
153
154 scope = match scope {
155 Scope::DeriveHelpers(LocalExpnId::ROOT) => Scope::DeriveHelpersCompat,
156 Scope::DeriveHelpers(expn_id) => {
157 let expn_data = expn_id.expn_data();
159 match expn_data.kind {
160 ExpnKind::Root
161 | ExpnKind::Macro(MacroKind::Bang | MacroKind::Derive, _) => {
162 Scope::DeriveHelpersCompat
163 }
164 _ => Scope::DeriveHelpers(expn_data.parent.expect_local()),
165 }
166 }
167 Scope::DeriveHelpersCompat => Scope::MacroRules(parent_scope.macro_rules),
168 Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() {
169 MacroRulesScope::Binding(binding) => {
170 Scope::MacroRules(binding.parent_macro_rules_scope)
171 }
172 MacroRulesScope::Invocation(invoc_id) => {
173 Scope::MacroRules(self.invocation_parent_scopes[&invoc_id].macro_rules)
174 }
175 MacroRulesScope::Empty => Scope::Module(module, None),
176 },
177 Scope::Module(..) if module_and_extern_prelude => match ns {
178 TypeNS => {
179 ctxt.adjust(ExpnId::root());
180 Scope::ExternPrelude
181 }
182 ValueNS | MacroNS => break,
183 },
184 Scope::Module(module, prev_lint_id) => {
185 use_prelude = !module.no_implicit_prelude;
186 let derive_fallback_lint_id = match scope_set {
187 ScopeSet::Late(.., lint_id) => lint_id,
188 _ => None,
189 };
190 match self.hygienic_lexical_parent(module, &mut ctxt, derive_fallback_lint_id) {
191 Some((parent_module, lint_id)) => {
192 Scope::Module(parent_module, lint_id.or(prev_lint_id))
193 }
194 None => {
195 ctxt.adjust(ExpnId::root());
196 match ns {
197 TypeNS => Scope::ExternPrelude,
198 ValueNS => Scope::StdLibPrelude,
199 MacroNS => Scope::MacroUsePrelude,
200 }
201 }
202 }
203 }
204 Scope::MacroUsePrelude => Scope::StdLibPrelude,
205 Scope::BuiltinAttrs => break, Scope::ExternPrelude if module_and_extern_prelude => break,
207 Scope::ExternPrelude => Scope::ToolPrelude,
208 Scope::ToolPrelude => Scope::StdLibPrelude,
209 Scope::StdLibPrelude => match ns {
210 TypeNS => Scope::BuiltinTypes,
211 ValueNS => break, MacroNS => Scope::BuiltinAttrs,
213 },
214 Scope::BuiltinTypes => break, };
216 }
217
218 None
219 }
220
221 fn hygienic_lexical_parent(
222 &self,
223 module: Module<'ra>,
224 ctxt: &mut SyntaxContext,
225 derive_fallback_lint_id: Option<NodeId>,
226 ) -> Option<(Module<'ra>, Option<NodeId>)> {
227 if !module.expansion.outer_expn_is_descendant_of(*ctxt) {
228 return Some((self.expn_def_scope(ctxt.remove_mark()), None));
229 }
230
231 if let ModuleKind::Block = module.kind {
232 return Some((module.parent.unwrap().nearest_item_scope(), None));
233 }
234
235 if derive_fallback_lint_id.is_some()
247 && let Some(parent) = module.parent
248 && module.expansion != parent.expansion
250 && module.expansion.is_descendant_of(parent.expansion)
252 && let Some(def_id) = module.expansion.expn_data().macro_def_id
254 {
255 let ext = &self.get_macro_by_def_id(def_id).ext;
256 if ext.builtin_name.is_none()
257 && ext.macro_kind() == MacroKind::Derive
258 && parent.expansion.outer_expn_is_descendant_of(*ctxt)
259 {
260 return Some((parent, derive_fallback_lint_id));
261 }
262 }
263
264 None
265 }
266
267 #[instrument(level = "debug", skip(self, ribs))]
285 pub(crate) fn resolve_ident_in_lexical_scope(
286 &mut self,
287 mut ident: Ident,
288 ns: Namespace,
289 parent_scope: &ParentScope<'ra>,
290 finalize: Option<Finalize>,
291 ribs: &[Rib<'ra>],
292 ignore_binding: Option<NameBinding<'ra>>,
293 ) -> Option<LexicalScopeBinding<'ra>> {
294 assert!(ns == TypeNS || ns == ValueNS);
295 let orig_ident = ident;
296 let (general_span, normalized_span) = if ident.name == kw::SelfUpper {
297 let empty_span = ident.span.with_ctxt(SyntaxContext::root());
299 (empty_span, empty_span)
300 } else if ns == TypeNS {
301 let normalized_span = ident.span.normalize_to_macros_2_0();
302 (normalized_span, normalized_span)
303 } else {
304 (ident.span.normalize_to_macro_rules(), ident.span.normalize_to_macros_2_0())
305 };
306 ident.span = general_span;
307 let normalized_ident = Ident { span: normalized_span, ..ident };
308
309 let mut module = self.graph_root;
311 for (i, rib) in ribs.iter().enumerate().rev() {
312 debug!("walk rib\n{:?}", rib.bindings);
313 let rib_ident = if rib.kind.contains_params() { normalized_ident } else { ident };
316 if let Some((original_rib_ident_def, res)) = rib.bindings.get_key_value(&rib_ident) {
317 return Some(LexicalScopeBinding::Res(self.validate_res_from_ribs(
319 i,
320 rib_ident,
321 *res,
322 finalize.map(|finalize| finalize.path_span),
323 *original_rib_ident_def,
324 ribs,
325 )));
326 }
327
328 module = match rib.kind {
329 RibKind::Module(module) => module,
330 RibKind::MacroDefinition(def) if def == self.macro_def(ident.span.ctxt()) => {
331 ident.span.remove_mark();
334 continue;
335 }
336 _ => continue,
337 };
338
339 match module.kind {
340 ModuleKind::Block => {} _ => break,
342 }
343
344 let item = self.resolve_ident_in_module_unadjusted(
345 ModuleOrUniformRoot::Module(module),
346 ident,
347 ns,
348 parent_scope,
349 Shadowing::Unrestricted,
350 finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }),
351 ignore_binding,
352 None,
353 );
354 if let Ok(binding) = item {
355 return Some(LexicalScopeBinding::Item(binding));
357 }
358 }
359 self.early_resolve_ident_in_lexical_scope(
360 orig_ident,
361 ScopeSet::Late(ns, module, finalize.map(|finalize| finalize.node_id)),
362 parent_scope,
363 finalize,
364 finalize.is_some(),
365 ignore_binding,
366 None,
367 )
368 .ok()
369 .map(LexicalScopeBinding::Item)
370 }
371
372 #[instrument(level = "debug", skip(self))]
378 pub(crate) fn early_resolve_ident_in_lexical_scope(
379 &mut self,
380 orig_ident: Ident,
381 scope_set: ScopeSet<'ra>,
382 parent_scope: &ParentScope<'ra>,
383 finalize: Option<Finalize>,
384 force: bool,
385 ignore_binding: Option<NameBinding<'ra>>,
386 ignore_import: Option<Import<'ra>>,
387 ) -> Result<NameBinding<'ra>, Determinacy> {
388 bitflags::bitflags! {
389 #[derive(Clone, Copy)]
390 struct Flags: u8 {
391 const MACRO_RULES = 1 << 0;
392 const MODULE = 1 << 1;
393 const MISC_SUGGEST_CRATE = 1 << 2;
394 const MISC_SUGGEST_SELF = 1 << 3;
395 const MISC_FROM_PRELUDE = 1 << 4;
396 }
397 }
398
399 assert!(force || finalize.is_none()); if orig_ident.is_path_segment_keyword() {
403 return Err(Determinacy::Determined);
404 }
405
406 let (ns, macro_kind) = match scope_set {
407 ScopeSet::All(ns)
408 | ScopeSet::ModuleAndExternPrelude(ns, _)
409 | ScopeSet::Late(ns, ..) => (ns, None),
410 ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
411 };
412
413 let mut innermost_result: Option<(NameBinding<'_>, Flags)> = None;
425 let mut determinacy = Determinacy::Determined;
426
427 let break_result = self.visit_scopes(
429 scope_set,
430 parent_scope,
431 orig_ident.span.ctxt(),
432 |this, scope, use_prelude, ctxt| {
433 let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt));
434 let result = match scope {
435 Scope::DeriveHelpers(expn_id) => {
436 if let Some(binding) = this.helper_attrs.get(&expn_id).and_then(|attrs| {
437 attrs.iter().rfind(|(i, _)| ident == *i).map(|(_, binding)| *binding)
438 }) {
439 Ok((binding, Flags::empty()))
440 } else {
441 Err(Determinacy::Determined)
442 }
443 }
444 Scope::DeriveHelpersCompat => {
445 let mut result = Err(Determinacy::Determined);
451 for derive in parent_scope.derives {
452 let parent_scope = &ParentScope { derives: &[], ..*parent_scope };
453 match this.resolve_macro_path(
454 derive,
455 Some(MacroKind::Derive),
456 parent_scope,
457 true,
458 force,
459 ignore_import,
460 None,
461 ) {
462 Ok((Some(ext), _)) => {
463 if ext.helper_attrs.contains(&ident.name) {
464 let binding = this.arenas.new_pub_res_binding(
465 Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat),
466 derive.span,
467 LocalExpnId::ROOT,
468 );
469 result = Ok((binding, Flags::empty()));
470 break;
471 }
472 }
473 Ok(_) | Err(Determinacy::Determined) => {}
474 Err(Determinacy::Undetermined) => {
475 result = Err(Determinacy::Undetermined)
476 }
477 }
478 }
479 result
480 }
481 Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() {
482 MacroRulesScope::Binding(macro_rules_binding)
483 if ident == macro_rules_binding.ident =>
484 {
485 Ok((macro_rules_binding.binding, Flags::MACRO_RULES))
486 }
487 MacroRulesScope::Invocation(_) => Err(Determinacy::Undetermined),
488 _ => Err(Determinacy::Determined),
489 },
490 Scope::Module(module, derive_fallback_lint_id) => {
491 let (adjusted_parent_scope, finalize) =
492 if matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..)) {
493 (parent_scope, finalize)
494 } else {
495 (
496 &ParentScope { module, ..*parent_scope },
497 finalize.map(|f| Finalize { used: Used::Scope, ..f }),
498 )
499 };
500 let binding = this.resolve_ident_in_module_unadjusted(
501 ModuleOrUniformRoot::Module(module),
502 ident,
503 ns,
504 adjusted_parent_scope,
505 if matches!(scope_set, ScopeSet::Late(..)) {
506 Shadowing::Unrestricted
507 } else {
508 Shadowing::Restricted
509 },
510 finalize,
511 ignore_binding,
512 ignore_import,
513 );
514 match binding {
515 Ok(binding) => {
516 if let Some(lint_id) = derive_fallback_lint_id {
517 this.lint_buffer.buffer_lint(
518 PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
519 lint_id,
520 orig_ident.span,
521 BuiltinLintDiag::ProcMacroDeriveResolutionFallback {
522 span: orig_ident.span,
523 ns,
524 ident,
525 },
526 );
527 }
528 let misc_flags = if module == this.graph_root {
529 Flags::MISC_SUGGEST_CRATE
530 } else if module.is_normal() {
531 Flags::MISC_SUGGEST_SELF
532 } else {
533 Flags::empty()
534 };
535 Ok((binding, Flags::MODULE | misc_flags))
536 }
537 Err((Determinacy::Undetermined, Weak::No)) => {
538 return Some(Err(Determinacy::determined(force)));
539 }
540 Err((Determinacy::Undetermined, Weak::Yes)) => {
541 Err(Determinacy::Undetermined)
542 }
543 Err((Determinacy::Determined, _)) => Err(Determinacy::Determined),
544 }
545 }
546 Scope::MacroUsePrelude => {
547 match this.macro_use_prelude.get(&ident.name).cloned() {
548 Some(binding) => Ok((binding, Flags::MISC_FROM_PRELUDE)),
549 None => Err(Determinacy::determined(
550 this.graph_root.unexpanded_invocations.borrow().is_empty(),
551 )),
552 }
553 }
554 Scope::BuiltinAttrs => match this.builtin_attrs_bindings.get(&ident.name) {
555 Some(binding) => Ok((*binding, Flags::empty())),
556 None => Err(Determinacy::Determined),
557 },
558 Scope::ExternPrelude => {
559 match this.extern_prelude_get(ident, finalize.is_some()) {
560 Some(binding) => Ok((binding, Flags::empty())),
561 None => Err(Determinacy::determined(
562 this.graph_root.unexpanded_invocations.borrow().is_empty(),
563 )),
564 }
565 }
566 Scope::ToolPrelude => match this.registered_tool_bindings.get(&ident) {
567 Some(binding) => Ok((*binding, Flags::empty())),
568 None => Err(Determinacy::Determined),
569 },
570 Scope::StdLibPrelude => {
571 let mut result = Err(Determinacy::Determined);
572 if let Some(prelude) = this.prelude
573 && let Ok(binding) = this.resolve_ident_in_module_unadjusted(
574 ModuleOrUniformRoot::Module(prelude),
575 ident,
576 ns,
577 parent_scope,
578 Shadowing::Unrestricted,
579 None,
580 ignore_binding,
581 ignore_import,
582 )
583 && (matches!(use_prelude, UsePrelude::Yes)
584 || this.is_builtin_macro(binding.res()))
585 {
586 result = Ok((binding, Flags::MISC_FROM_PRELUDE));
587 }
588
589 result
590 }
591 Scope::BuiltinTypes => match this.builtin_types_bindings.get(&ident.name) {
592 Some(binding) => {
593 if matches!(ident.name, sym::f16)
594 && !this.tcx.features().f16()
595 && !ident.span.allows_unstable(sym::f16)
596 && finalize.is_some()
597 && innermost_result.is_none()
598 {
599 feature_err(
600 this.tcx.sess,
601 sym::f16,
602 ident.span,
603 "the type `f16` is unstable",
604 )
605 .emit();
606 }
607 if matches!(ident.name, sym::f128)
608 && !this.tcx.features().f128()
609 && !ident.span.allows_unstable(sym::f128)
610 && finalize.is_some()
611 && innermost_result.is_none()
612 {
613 feature_err(
614 this.tcx.sess,
615 sym::f128,
616 ident.span,
617 "the type `f128` is unstable",
618 )
619 .emit();
620 }
621 Ok((*binding, Flags::empty()))
622 }
623 None => Err(Determinacy::Determined),
624 },
625 };
626
627 match result {
628 Ok((binding, flags))
629 if sub_namespace_match(binding.macro_kind(), macro_kind) =>
630 {
631 if finalize.is_none() || matches!(scope_set, ScopeSet::Late(..)) {
632 return Some(Ok(binding));
633 }
634
635 if let Some((innermost_binding, innermost_flags)) = innermost_result {
636 let (res, innermost_res) = (binding.res(), innermost_binding.res());
638 if res != innermost_res {
639 let is_builtin = |res| {
640 matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Builtin(..)))
641 };
642 let derive_helper =
643 Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
644 let derive_helper_compat =
645 Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat);
646
647 let ambiguity_error_kind = if is_builtin(innermost_res)
648 || is_builtin(res)
649 {
650 Some(AmbiguityKind::BuiltinAttr)
651 } else if innermost_res == derive_helper_compat
652 || res == derive_helper_compat && innermost_res != derive_helper
653 {
654 Some(AmbiguityKind::DeriveHelper)
655 } else if innermost_flags.contains(Flags::MACRO_RULES)
656 && flags.contains(Flags::MODULE)
657 && !this.disambiguate_macro_rules_vs_modularized(
658 innermost_binding,
659 binding,
660 )
661 || flags.contains(Flags::MACRO_RULES)
662 && innermost_flags.contains(Flags::MODULE)
663 && !this.disambiguate_macro_rules_vs_modularized(
664 binding,
665 innermost_binding,
666 )
667 {
668 Some(AmbiguityKind::MacroRulesVsModularized)
669 } else if innermost_binding.is_glob_import() {
670 Some(AmbiguityKind::GlobVsOuter)
671 } else if innermost_binding
672 .may_appear_after(parent_scope.expansion, binding)
673 {
674 Some(AmbiguityKind::MoreExpandedVsOuter)
675 } else {
676 None
677 };
678 if let Some(kind) = ambiguity_error_kind {
679 let misc = |f: Flags| {
680 if f.contains(Flags::MISC_SUGGEST_CRATE) {
681 AmbiguityErrorMisc::SuggestCrate
682 } else if f.contains(Flags::MISC_SUGGEST_SELF) {
683 AmbiguityErrorMisc::SuggestSelf
684 } else if f.contains(Flags::MISC_FROM_PRELUDE) {
685 AmbiguityErrorMisc::FromPrelude
686 } else {
687 AmbiguityErrorMisc::None
688 }
689 };
690 this.ambiguity_errors.push(AmbiguityError {
691 kind,
692 ident: orig_ident,
693 b1: innermost_binding,
694 b2: binding,
695 warning: false,
696 misc1: misc(innermost_flags),
697 misc2: misc(flags),
698 });
699 return Some(Ok(innermost_binding));
700 }
701 }
702 } else {
703 innermost_result = Some((binding, flags));
705 }
706 }
707 Ok(..) | Err(Determinacy::Determined) => {}
708 Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined,
709 }
710
711 None
712 },
713 );
714
715 if let Some(break_result) = break_result {
716 return break_result;
717 }
718
719 if let Some((binding, _)) = innermost_result {
721 return Ok(binding);
722 }
723
724 Err(Determinacy::determined(determinacy == Determinacy::Determined || force))
725 }
726
727 #[instrument(level = "debug", skip(self))]
728 pub(crate) fn maybe_resolve_ident_in_module(
729 &mut self,
730 module: ModuleOrUniformRoot<'ra>,
731 ident: Ident,
732 ns: Namespace,
733 parent_scope: &ParentScope<'ra>,
734 ignore_import: Option<Import<'ra>>,
735 ) -> Result<NameBinding<'ra>, Determinacy> {
736 self.resolve_ident_in_module(module, ident, ns, parent_scope, None, None, ignore_import)
737 .map_err(|(determinacy, _)| determinacy)
738 }
739
740 #[instrument(level = "debug", skip(self))]
741 pub(crate) fn resolve_ident_in_module(
742 &mut self,
743 module: ModuleOrUniformRoot<'ra>,
744 mut ident: Ident,
745 ns: Namespace,
746 parent_scope: &ParentScope<'ra>,
747 finalize: Option<Finalize>,
748 ignore_binding: Option<NameBinding<'ra>>,
749 ignore_import: Option<Import<'ra>>,
750 ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
751 let tmp_parent_scope;
752 let mut adjusted_parent_scope = parent_scope;
753 match module {
754 ModuleOrUniformRoot::Module(m) => {
755 if let Some(def) = ident.span.normalize_to_macros_2_0_and_adjust(m.expansion) {
756 tmp_parent_scope =
757 ParentScope { module: self.expn_def_scope(def), ..*parent_scope };
758 adjusted_parent_scope = &tmp_parent_scope;
759 }
760 }
761 ModuleOrUniformRoot::ExternPrelude => {
762 ident.span.normalize_to_macros_2_0_and_adjust(ExpnId::root());
763 }
764 ModuleOrUniformRoot::ModuleAndExternPrelude(..) | ModuleOrUniformRoot::CurrentScope => {
765 }
767 }
768 self.resolve_ident_in_module_unadjusted(
769 module,
770 ident,
771 ns,
772 adjusted_parent_scope,
773 Shadowing::Unrestricted,
774 finalize,
775 ignore_binding,
776 ignore_import,
777 )
778 }
779
780 #[instrument(level = "debug", skip(self))]
783 fn resolve_ident_in_module_unadjusted(
784 &mut self,
785 module: ModuleOrUniformRoot<'ra>,
786 ident: Ident,
787 ns: Namespace,
788 parent_scope: &ParentScope<'ra>,
789 shadowing: Shadowing,
790 finalize: Option<Finalize>,
791 ignore_binding: Option<NameBinding<'ra>>,
794 ignore_import: Option<Import<'ra>>,
795 ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
796 let module = match module {
797 ModuleOrUniformRoot::Module(module) => module,
798 ModuleOrUniformRoot::ModuleAndExternPrelude(module) => {
799 assert_eq!(shadowing, Shadowing::Unrestricted);
800 let binding = self.early_resolve_ident_in_lexical_scope(
801 ident,
802 ScopeSet::ModuleAndExternPrelude(ns, module),
803 parent_scope,
804 finalize,
805 finalize.is_some(),
806 ignore_binding,
807 ignore_import,
808 );
809 return binding.map_err(|determinacy| (determinacy, Weak::No));
810 }
811 ModuleOrUniformRoot::ExternPrelude => {
812 assert_eq!(shadowing, Shadowing::Unrestricted);
813 return if ns != TypeNS {
814 Err((Determined, Weak::No))
815 } else if let Some(binding) = self.extern_prelude_get(ident, finalize.is_some()) {
816 Ok(binding)
817 } else if !self.graph_root.unexpanded_invocations.borrow().is_empty() {
818 Err((Undetermined, Weak::No))
820 } else {
821 Err((Determined, Weak::No))
822 };
823 }
824 ModuleOrUniformRoot::CurrentScope => {
825 assert_eq!(shadowing, Shadowing::Unrestricted);
826 if ns == TypeNS {
827 if ident.name == kw::Crate || ident.name == kw::DollarCrate {
828 let module = self.resolve_crate_root(ident);
829 return Ok(module.self_binding.unwrap());
830 } else if ident.name == kw::Super || ident.name == kw::SelfLower {
831 }
835 }
836
837 let binding = self.early_resolve_ident_in_lexical_scope(
838 ident,
839 ScopeSet::All(ns),
840 parent_scope,
841 finalize,
842 finalize.is_some(),
843 ignore_binding,
844 ignore_import,
845 );
846 return binding.map_err(|determinacy| (determinacy, Weak::No));
847 }
848 };
849
850 let key = BindingKey::new(ident, ns);
851 let resolution = &*self
855 .resolution_or_default(module, key)
856 .try_borrow_mut()
857 .map_err(|_| (Determined, Weak::No))?;
858
859 let binding = [resolution.non_glob_binding, resolution.glob_binding]
864 .into_iter()
865 .find_map(|binding| if binding == ignore_binding { None } else { binding });
866
867 if let Some(finalize) = finalize {
868 return self.finalize_module_binding(
869 ident,
870 binding,
871 if resolution.non_glob_binding.is_some() { resolution.glob_binding } else { None },
872 parent_scope,
873 finalize,
874 shadowing,
875 );
876 }
877
878 let check_usable = |this: &Self, binding: NameBinding<'ra>| {
879 let usable = this.is_accessible_from(binding.vis, parent_scope.module);
880 if usable { Ok(binding) } else { Err((Determined, Weak::No)) }
881 };
882
883 if let Some(binding) = binding
885 && !binding.is_glob_import()
886 {
887 return check_usable(self, binding);
888 }
889
890 if self.single_import_can_define_name(
895 &resolution,
896 binding,
897 ns,
898 ignore_import,
899 ignore_binding,
900 parent_scope,
901 ) {
902 return Err((Undetermined, Weak::No));
903 }
904
905 if let Some(binding) = binding {
918 if binding.determined() || ns == MacroNS || shadowing == Shadowing::Restricted {
919 return check_usable(self, binding);
920 } else {
921 return Err((Undetermined, Weak::No));
922 }
923 }
924
925 if !module.unexpanded_invocations.borrow().is_empty() {
936 return Err((Undetermined, Weak::Yes));
937 }
938
939 for glob_import in module.globs.borrow().iter() {
942 if ignore_import == Some(*glob_import) {
943 continue;
944 }
945 if !self.is_accessible_from(glob_import.vis, parent_scope.module) {
946 continue;
947 }
948 let module = match glob_import.imported_module.get() {
949 Some(ModuleOrUniformRoot::Module(module)) => module,
950 Some(_) => continue,
951 None => return Err((Undetermined, Weak::Yes)),
952 };
953 let tmp_parent_scope;
954 let (mut adjusted_parent_scope, mut ident) =
955 (parent_scope, ident.normalize_to_macros_2_0());
956 match ident.span.glob_adjust(module.expansion, glob_import.span) {
957 Some(Some(def)) => {
958 tmp_parent_scope =
959 ParentScope { module: self.expn_def_scope(def), ..*parent_scope };
960 adjusted_parent_scope = &tmp_parent_scope;
961 }
962 Some(None) => {}
963 None => continue,
964 };
965 let result = self.resolve_ident_in_module_unadjusted(
966 ModuleOrUniformRoot::Module(module),
967 ident,
968 ns,
969 adjusted_parent_scope,
970 Shadowing::Unrestricted,
971 None,
972 ignore_binding,
973 ignore_import,
974 );
975
976 match result {
977 Err((Determined, _)) => continue,
978 Ok(binding)
979 if !self.is_accessible_from(binding.vis, glob_import.parent_scope.module) =>
980 {
981 continue;
982 }
983 Ok(_) | Err((Undetermined, _)) => return Err((Undetermined, Weak::Yes)),
984 }
985 }
986
987 Err((Determined, Weak::No))
989 }
990
991 fn finalize_module_binding(
992 &mut self,
993 ident: Ident,
994 binding: Option<NameBinding<'ra>>,
995 shadowed_glob: Option<NameBinding<'ra>>,
996 parent_scope: &ParentScope<'ra>,
997 finalize: Finalize,
998 shadowing: Shadowing,
999 ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
1000 let Finalize { path_span, report_private, used, root_span, .. } = finalize;
1001
1002 let Some(binding) = binding else {
1003 return Err((Determined, Weak::No));
1004 };
1005
1006 if !self.is_accessible_from(binding.vis, parent_scope.module) {
1007 if report_private {
1008 self.privacy_errors.push(PrivacyError {
1009 ident,
1010 binding,
1011 dedup_span: path_span,
1012 outermost_res: None,
1013 parent_scope: *parent_scope,
1014 single_nested: path_span != root_span,
1015 });
1016 } else {
1017 return Err((Determined, Weak::No));
1018 }
1019 }
1020
1021 if let Some(shadowed_glob) = shadowed_glob
1023 && shadowing == Shadowing::Restricted
1024 && binding.expansion != LocalExpnId::ROOT
1025 && binding.res() != shadowed_glob.res()
1026 {
1027 self.ambiguity_errors.push(AmbiguityError {
1028 kind: AmbiguityKind::GlobVsExpanded,
1029 ident,
1030 b1: binding,
1031 b2: shadowed_glob,
1032 warning: false,
1033 misc1: AmbiguityErrorMisc::None,
1034 misc2: AmbiguityErrorMisc::None,
1035 });
1036 }
1037
1038 if shadowing == Shadowing::Unrestricted
1039 && binding.expansion != LocalExpnId::ROOT
1040 && let NameBindingKind::Import { import, .. } = binding.kind
1041 && matches!(import.kind, ImportKind::MacroExport)
1042 {
1043 self.macro_expanded_macro_export_errors.insert((path_span, binding.span));
1044 }
1045
1046 self.record_use(ident, binding, used);
1047 return Ok(binding);
1048 }
1049
1050 fn single_import_can_define_name(
1053 &mut self,
1054 resolution: &NameResolution<'ra>,
1055 binding: Option<NameBinding<'ra>>,
1056 ns: Namespace,
1057 ignore_import: Option<Import<'ra>>,
1058 ignore_binding: Option<NameBinding<'ra>>,
1059 parent_scope: &ParentScope<'ra>,
1060 ) -> bool {
1061 for single_import in &resolution.single_imports {
1062 if ignore_import == Some(*single_import) {
1063 continue;
1064 }
1065 if !self.is_accessible_from(single_import.vis, parent_scope.module) {
1066 continue;
1067 }
1068 if let Some(ignored) = ignore_binding
1069 && let NameBindingKind::Import { import, .. } = ignored.kind
1070 && import == *single_import
1071 {
1072 continue;
1073 }
1074
1075 let Some(module) = single_import.imported_module.get() else {
1076 return true;
1077 };
1078 let ImportKind::Single { source, target, bindings, .. } = &single_import.kind else {
1079 unreachable!();
1080 };
1081 if source != target {
1082 if bindings.iter().all(|binding| binding.get().binding().is_none()) {
1083 return true;
1084 } else if bindings[ns].get().binding().is_none() && binding.is_some() {
1085 return true;
1086 }
1087 }
1088
1089 match self.resolve_ident_in_module(
1090 module,
1091 *source,
1092 ns,
1093 &single_import.parent_scope,
1094 None,
1095 ignore_binding,
1096 ignore_import,
1097 ) {
1098 Err((Determined, _)) => continue,
1099 Ok(binding)
1100 if !self.is_accessible_from(binding.vis, single_import.parent_scope.module) =>
1101 {
1102 continue;
1103 }
1104 Ok(_) | Err((Undetermined, _)) => {
1105 return true;
1106 }
1107 }
1108 }
1109
1110 false
1111 }
1112
1113 #[instrument(level = "debug", skip(self, all_ribs))]
1115 fn validate_res_from_ribs(
1116 &mut self,
1117 rib_index: usize,
1118 rib_ident: Ident,
1119 mut res: Res,
1120 finalize: Option<Span>,
1121 original_rib_ident_def: Ident,
1122 all_ribs: &[Rib<'ra>],
1123 ) -> Res {
1124 debug!("validate_res_from_ribs({:?})", res);
1125 let ribs = &all_ribs[rib_index + 1..];
1126
1127 if let RibKind::ForwardGenericParamBan(reason) = all_ribs[rib_index].kind {
1130 if let Some(span) = finalize {
1131 let res_error = if rib_ident.name == kw::SelfUpper {
1132 ResolutionError::ForwardDeclaredSelf(reason)
1133 } else {
1134 ResolutionError::ForwardDeclaredGenericParam(rib_ident.name, reason)
1135 };
1136 self.report_error(span, res_error);
1137 }
1138 assert_eq!(res, Res::Err);
1139 return Res::Err;
1140 }
1141
1142 match res {
1143 Res::Local(_) => {
1144 use ResolutionError::*;
1145 let mut res_err = None;
1146
1147 for rib in ribs {
1148 match rib.kind {
1149 RibKind::Normal
1150 | RibKind::FnOrCoroutine
1151 | RibKind::Module(..)
1152 | RibKind::MacroDefinition(..)
1153 | RibKind::ForwardGenericParamBan(_) => {
1154 }
1156 RibKind::Item(..) | RibKind::AssocItem => {
1157 if let Some(span) = finalize {
1161 res_err = Some((span, CannotCaptureDynamicEnvironmentInFnItem));
1166 }
1167 }
1168 RibKind::ConstantItem(_, item) => {
1169 if let Some(span) = finalize {
1171 let (span, resolution_error) = match item {
1172 None if rib_ident.name == kw::SelfLower => {
1173 (span, LowercaseSelf)
1174 }
1175 None => {
1176 let sm = self.tcx.sess.source_map();
1182 let type_span = match sm.span_look_ahead(
1183 original_rib_ident_def.span,
1184 ":",
1185 None,
1186 ) {
1187 None => {
1188 Some(original_rib_ident_def.span.shrink_to_hi())
1189 }
1190 Some(_) => None,
1191 };
1192 (
1193 rib_ident.span,
1194 AttemptToUseNonConstantValueInConstant {
1195 ident: original_rib_ident_def,
1196 suggestion: "const",
1197 current: "let",
1198 type_span,
1199 },
1200 )
1201 }
1202 Some((ident, kind)) => (
1203 span,
1204 AttemptToUseNonConstantValueInConstant {
1205 ident,
1206 suggestion: "let",
1207 current: kind.as_str(),
1208 type_span: None,
1209 },
1210 ),
1211 };
1212 self.report_error(span, resolution_error);
1213 }
1214 return Res::Err;
1215 }
1216 RibKind::ConstParamTy => {
1217 if let Some(span) = finalize {
1218 self.report_error(
1219 span,
1220 ParamInTyOfConstParam { name: rib_ident.name },
1221 );
1222 }
1223 return Res::Err;
1224 }
1225 RibKind::InlineAsmSym => {
1226 if let Some(span) = finalize {
1227 self.report_error(span, InvalidAsmSym);
1228 }
1229 return Res::Err;
1230 }
1231 }
1232 }
1233 if let Some((span, res_err)) = res_err {
1234 self.report_error(span, res_err);
1235 return Res::Err;
1236 }
1237 }
1238 Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {
1239 for rib in ribs {
1240 let (has_generic_params, def_kind) = match rib.kind {
1241 RibKind::Normal
1242 | RibKind::FnOrCoroutine
1243 | RibKind::Module(..)
1244 | RibKind::MacroDefinition(..)
1245 | RibKind::InlineAsmSym
1246 | RibKind::AssocItem
1247 | RibKind::ForwardGenericParamBan(_) => {
1248 continue;
1250 }
1251
1252 RibKind::ConstParamTy => {
1253 if !self.tcx.features().generic_const_parameter_types() {
1254 if let Some(span) = finalize {
1255 self.report_error(
1256 span,
1257 ResolutionError::ParamInTyOfConstParam {
1258 name: rib_ident.name,
1259 },
1260 );
1261 }
1262 return Res::Err;
1263 } else {
1264 continue;
1265 }
1266 }
1267
1268 RibKind::ConstantItem(trivial, _) => {
1269 if let ConstantHasGenerics::No(cause) = trivial {
1270 if let Res::SelfTyAlias {
1275 alias_to: def,
1276 forbid_generic: _,
1277 is_trait_impl,
1278 } = res
1279 {
1280 res = Res::SelfTyAlias {
1281 alias_to: def,
1282 forbid_generic: true,
1283 is_trait_impl,
1284 }
1285 } else {
1286 if let Some(span) = finalize {
1287 let error = match cause {
1288 NoConstantGenericsReason::IsEnumDiscriminant => {
1289 ResolutionError::ParamInEnumDiscriminant {
1290 name: rib_ident.name,
1291 param_kind: ParamKindInEnumDiscriminant::Type,
1292 }
1293 }
1294 NoConstantGenericsReason::NonTrivialConstArg => {
1295 ResolutionError::ParamInNonTrivialAnonConst {
1296 name: rib_ident.name,
1297 param_kind:
1298 ParamKindInNonTrivialAnonConst::Type,
1299 }
1300 }
1301 };
1302 let _: ErrorGuaranteed = self.report_error(span, error);
1303 }
1304
1305 return Res::Err;
1306 }
1307 }
1308
1309 continue;
1310 }
1311
1312 RibKind::Item(has_generic_params, def_kind) => {
1314 (has_generic_params, def_kind)
1315 }
1316 };
1317
1318 if let Some(span) = finalize {
1319 self.report_error(
1320 span,
1321 ResolutionError::GenericParamsFromOuterItem(
1322 res,
1323 has_generic_params,
1324 def_kind,
1325 ),
1326 );
1327 }
1328 return Res::Err;
1329 }
1330 }
1331 Res::Def(DefKind::ConstParam, _) => {
1332 for rib in ribs {
1333 let (has_generic_params, def_kind) = match rib.kind {
1334 RibKind::Normal
1335 | RibKind::FnOrCoroutine
1336 | RibKind::Module(..)
1337 | RibKind::MacroDefinition(..)
1338 | RibKind::InlineAsmSym
1339 | RibKind::AssocItem
1340 | RibKind::ForwardGenericParamBan(_) => continue,
1341
1342 RibKind::ConstParamTy => {
1343 if !self.tcx.features().generic_const_parameter_types() {
1344 if let Some(span) = finalize {
1345 self.report_error(
1346 span,
1347 ResolutionError::ParamInTyOfConstParam {
1348 name: rib_ident.name,
1349 },
1350 );
1351 }
1352 return Res::Err;
1353 } else {
1354 continue;
1355 }
1356 }
1357
1358 RibKind::ConstantItem(trivial, _) => {
1359 if let ConstantHasGenerics::No(cause) = trivial {
1360 if let Some(span) = finalize {
1361 let error = match cause {
1362 NoConstantGenericsReason::IsEnumDiscriminant => {
1363 ResolutionError::ParamInEnumDiscriminant {
1364 name: rib_ident.name,
1365 param_kind: ParamKindInEnumDiscriminant::Const,
1366 }
1367 }
1368 NoConstantGenericsReason::NonTrivialConstArg => {
1369 ResolutionError::ParamInNonTrivialAnonConst {
1370 name: rib_ident.name,
1371 param_kind: ParamKindInNonTrivialAnonConst::Const {
1372 name: rib_ident.name,
1373 },
1374 }
1375 }
1376 };
1377 self.report_error(span, error);
1378 }
1379
1380 return Res::Err;
1381 }
1382
1383 continue;
1384 }
1385
1386 RibKind::Item(has_generic_params, def_kind) => {
1387 (has_generic_params, def_kind)
1388 }
1389 };
1390
1391 if let Some(span) = finalize {
1393 self.report_error(
1394 span,
1395 ResolutionError::GenericParamsFromOuterItem(
1396 res,
1397 has_generic_params,
1398 def_kind,
1399 ),
1400 );
1401 }
1402 return Res::Err;
1403 }
1404 }
1405 _ => {}
1406 }
1407
1408 res
1409 }
1410
1411 #[instrument(level = "debug", skip(self))]
1412 pub(crate) fn maybe_resolve_path(
1413 &mut self,
1414 path: &[Segment],
1415 opt_ns: Option<Namespace>, parent_scope: &ParentScope<'ra>,
1417 ignore_import: Option<Import<'ra>>,
1418 ) -> PathResult<'ra> {
1419 self.resolve_path_with_ribs(path, opt_ns, parent_scope, None, None, None, ignore_import)
1420 }
1421
1422 #[instrument(level = "debug", skip(self))]
1423 pub(crate) fn resolve_path(
1424 &mut self,
1425 path: &[Segment],
1426 opt_ns: Option<Namespace>, parent_scope: &ParentScope<'ra>,
1428 finalize: Option<Finalize>,
1429 ignore_binding: Option<NameBinding<'ra>>,
1430 ignore_import: Option<Import<'ra>>,
1431 ) -> PathResult<'ra> {
1432 self.resolve_path_with_ribs(
1433 path,
1434 opt_ns,
1435 parent_scope,
1436 finalize,
1437 None,
1438 ignore_binding,
1439 ignore_import,
1440 )
1441 }
1442
1443 pub(crate) fn resolve_path_with_ribs(
1444 &mut self,
1445 path: &[Segment],
1446 opt_ns: Option<Namespace>, parent_scope: &ParentScope<'ra>,
1448 finalize: Option<Finalize>,
1449 ribs: Option<&PerNS<Vec<Rib<'ra>>>>,
1450 ignore_binding: Option<NameBinding<'ra>>,
1451 ignore_import: Option<Import<'ra>>,
1452 ) -> PathResult<'ra> {
1453 let mut module = None;
1454 let mut module_had_parse_errors = false;
1455 let mut allow_super = true;
1456 let mut second_binding = None;
1457
1458 let privacy_errors_len = self.privacy_errors.len();
1460
1461 for (segment_idx, &Segment { ident, id, .. }) in path.iter().enumerate() {
1462 debug!("resolve_path ident {} {:?} {:?}", segment_idx, ident, id);
1463 let record_segment_res = |this: &mut Self, res| {
1464 if finalize.is_some()
1465 && let Some(id) = id
1466 && !this.partial_res_map.contains_key(&id)
1467 {
1468 assert!(id != ast::DUMMY_NODE_ID, "Trying to resolve dummy id");
1469 this.record_partial_res(id, PartialRes::new(res));
1470 }
1471 };
1472
1473 let is_last = segment_idx + 1 == path.len();
1474 let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };
1475 let name = ident.name;
1476
1477 allow_super &= ns == TypeNS && (name == kw::SelfLower || name == kw::Super);
1478
1479 if ns == TypeNS {
1480 if allow_super && name == kw::Super {
1481 let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();
1482 let self_module = match segment_idx {
1483 0 => Some(self.resolve_self(&mut ctxt, parent_scope.module)),
1484 _ => match module {
1485 Some(ModuleOrUniformRoot::Module(module)) => Some(module),
1486 _ => None,
1487 },
1488 };
1489 if let Some(self_module) = self_module
1490 && let Some(parent) = self_module.parent
1491 {
1492 module =
1493 Some(ModuleOrUniformRoot::Module(self.resolve_self(&mut ctxt, parent)));
1494 continue;
1495 }
1496 return PathResult::failed(
1497 ident,
1498 false,
1499 finalize.is_some(),
1500 module_had_parse_errors,
1501 module,
1502 || ("there are too many leading `super` keywords".to_string(), None),
1503 );
1504 }
1505 if segment_idx == 0 {
1506 if name == kw::SelfLower {
1507 let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();
1508 let self_mod = self.resolve_self(&mut ctxt, parent_scope.module);
1509 if let Some(res) = self_mod.res() {
1510 record_segment_res(self, res);
1511 }
1512 module = Some(ModuleOrUniformRoot::Module(self_mod));
1513 continue;
1514 }
1515 if name == kw::PathRoot && ident.span.at_least_rust_2018() {
1516 module = Some(ModuleOrUniformRoot::ExternPrelude);
1517 continue;
1518 }
1519 if name == kw::PathRoot
1520 && ident.span.is_rust_2015()
1521 && self.tcx.sess.at_least_rust_2018()
1522 {
1523 let crate_root = self.resolve_crate_root(ident);
1525 module = Some(ModuleOrUniformRoot::ModuleAndExternPrelude(crate_root));
1526 continue;
1527 }
1528 if name == kw::PathRoot || name == kw::Crate || name == kw::DollarCrate {
1529 let crate_root = self.resolve_crate_root(ident);
1531 if let Some(res) = crate_root.res() {
1532 record_segment_res(self, res);
1533 }
1534 module = Some(ModuleOrUniformRoot::Module(crate_root));
1535 continue;
1536 }
1537 }
1538 }
1539
1540 if ident.is_path_segment_keyword() && segment_idx != 0 {
1542 return PathResult::failed(
1543 ident,
1544 false,
1545 finalize.is_some(),
1546 module_had_parse_errors,
1547 module,
1548 || {
1549 let name_str = if name == kw::PathRoot {
1550 "crate root".to_string()
1551 } else {
1552 format!("`{name}`")
1553 };
1554 let label = if segment_idx == 1 && path[0].ident.name == kw::PathRoot {
1555 format!("global paths cannot start with {name_str}")
1556 } else {
1557 format!("{name_str} in paths can only be used in start position")
1558 };
1559 (label, None)
1560 },
1561 );
1562 }
1563
1564 let binding = if let Some(module) = module {
1565 self.resolve_ident_in_module(
1566 module,
1567 ident,
1568 ns,
1569 parent_scope,
1570 finalize,
1571 ignore_binding,
1572 ignore_import,
1573 )
1574 .map_err(|(determinacy, _)| determinacy)
1575 } else if let Some(ribs) = ribs
1576 && let Some(TypeNS | ValueNS) = opt_ns
1577 {
1578 assert!(ignore_import.is_none());
1579 match self.resolve_ident_in_lexical_scope(
1580 ident,
1581 ns,
1582 parent_scope,
1583 finalize,
1584 &ribs[ns],
1585 ignore_binding,
1586 ) {
1587 Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
1589 Some(LexicalScopeBinding::Res(res)) => {
1591 record_segment_res(self, res);
1592 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1593 res,
1594 path.len() - 1,
1595 ));
1596 }
1597 _ => Err(Determinacy::determined(finalize.is_some())),
1598 }
1599 } else {
1600 self.early_resolve_ident_in_lexical_scope(
1601 ident,
1602 ScopeSet::All(ns),
1603 parent_scope,
1604 finalize,
1605 finalize.is_some(),
1606 ignore_binding,
1607 ignore_import,
1608 )
1609 };
1610
1611 match binding {
1612 Ok(binding) => {
1613 if segment_idx == 1 {
1614 second_binding = Some(binding);
1615 }
1616 let res = binding.res();
1617
1618 for error in &mut self.privacy_errors[privacy_errors_len..] {
1622 error.outermost_res = Some((res, ident));
1623 }
1624
1625 let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(res);
1626 if let Some(def_id) = binding.res().module_like_def_id() {
1627 if self.mods_with_parse_errors.contains(&def_id) {
1628 module_had_parse_errors = true;
1629 }
1630 module = Some(ModuleOrUniformRoot::Module(self.expect_module(def_id)));
1631 record_segment_res(self, res);
1632 } else if res == Res::ToolMod && !is_last && opt_ns.is_some() {
1633 if binding.is_import() {
1634 self.dcx().emit_err(errors::ToolModuleImported {
1635 span: ident.span,
1636 import: binding.span,
1637 });
1638 }
1639 let res = Res::NonMacroAttr(NonMacroAttrKind::Tool);
1640 return PathResult::NonModule(PartialRes::new(res));
1641 } else if res == Res::Err {
1642 return PathResult::NonModule(PartialRes::new(Res::Err));
1643 } else if opt_ns.is_some() && (is_last || maybe_assoc) {
1644 self.lint_if_path_starts_with_module(finalize, path, second_binding);
1645 record_segment_res(self, res);
1646 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1647 res,
1648 path.len() - segment_idx - 1,
1649 ));
1650 } else {
1651 return PathResult::failed(
1652 ident,
1653 is_last,
1654 finalize.is_some(),
1655 module_had_parse_errors,
1656 module,
1657 || {
1658 let label = format!(
1659 "`{ident}` is {} {}, not a module",
1660 res.article(),
1661 res.descr()
1662 );
1663 (label, None)
1664 },
1665 );
1666 }
1667 }
1668 Err(Undetermined) => return PathResult::Indeterminate,
1669 Err(Determined) => {
1670 if let Some(ModuleOrUniformRoot::Module(module)) = module
1671 && opt_ns.is_some()
1672 && !module.is_normal()
1673 {
1674 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1675 module.res().unwrap(),
1676 path.len() - segment_idx,
1677 ));
1678 }
1679
1680 return PathResult::failed(
1681 ident,
1682 is_last,
1683 finalize.is_some(),
1684 module_had_parse_errors,
1685 module,
1686 || {
1687 self.report_path_resolution_error(
1688 path,
1689 opt_ns,
1690 parent_scope,
1691 ribs,
1692 ignore_binding,
1693 ignore_import,
1694 module,
1695 segment_idx,
1696 ident,
1697 )
1698 },
1699 );
1700 }
1701 }
1702 }
1703
1704 self.lint_if_path_starts_with_module(finalize, path, second_binding);
1705
1706 PathResult::Module(match module {
1707 Some(module) => module,
1708 None if path.is_empty() => ModuleOrUniformRoot::CurrentScope,
1709 _ => bug!("resolve_path: non-empty path `{:?}` has no module", path),
1710 })
1711 }
1712}