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, is_absolute_path) = match scope_set {
97 ScopeSet::All(ns) => (ns, None, false),
98 ScopeSet::AbsolutePath(ns) => (ns, None, true),
99 ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind), false),
100 ScopeSet::Late(ns, ..) => (ns, None, false),
101 };
102 let module = match scope_set {
103 ScopeSet::Late(_, module, _) => module,
105 _ => parent_scope.module.nearest_item_scope(),
107 };
108 let mut scope = match ns {
109 _ if is_absolute_path => Scope::CrateRoot,
110 TypeNS | ValueNS => Scope::Module(module, None),
111 MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
112 };
113 let mut ctxt = ctxt.normalize_to_macros_2_0();
114 let mut use_prelude = !module.no_implicit_prelude;
115
116 loop {
117 let visit = match scope {
118 Scope::DeriveHelpers(expn_id) => {
120 !(expn_id == parent_scope.expansion && macro_kind == Some(MacroKind::Derive))
121 }
122 Scope::DeriveHelpersCompat => true,
123 Scope::MacroRules(macro_rules_scope) => {
124 while let MacroRulesScope::Invocation(invoc_id) = macro_rules_scope.get() {
129 if let Some(next_scope) = self.output_macro_rules_scopes.get(&invoc_id) {
130 macro_rules_scope.set(next_scope.get());
131 } else {
132 break;
133 }
134 }
135 true
136 }
137 Scope::CrateRoot => true,
138 Scope::Module(..) => true,
139 Scope::MacroUsePrelude => use_prelude || rust_2015,
140 Scope::BuiltinAttrs => true,
141 Scope::ExternPrelude => use_prelude || is_absolute_path,
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::CrateRoot => 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 is_absolute_path => 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) => (ns, None),
408 ScopeSet::AbsolutePath(ns) => (ns, None),
409 ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
410 ScopeSet::Late(ns, ..) => (ns, None),
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::CrateRoot => {
491 let root_ident = Ident::new(kw::PathRoot, ident.span);
492 let root_module = this.resolve_crate_root(root_ident);
493 let binding = this.resolve_ident_in_module(
494 ModuleOrUniformRoot::Module(root_module),
495 ident,
496 ns,
497 parent_scope,
498 finalize,
499 ignore_binding,
500 ignore_import,
501 );
502 match binding {
503 Ok(binding) => Ok((binding, Flags::MODULE | Flags::MISC_SUGGEST_CRATE)),
504 Err((Determinacy::Undetermined, Weak::No)) => {
505 return Some(Err(Determinacy::determined(force)));
506 }
507 Err((Determinacy::Undetermined, Weak::Yes)) => {
508 Err(Determinacy::Undetermined)
509 }
510 Err((Determinacy::Determined, _)) => Err(Determinacy::Determined),
511 }
512 }
513 Scope::Module(module, derive_fallback_lint_id) => {
514 let adjusted_parent_scope = &ParentScope { module, ..*parent_scope };
515 let binding = this.resolve_ident_in_module_unadjusted(
516 ModuleOrUniformRoot::Module(module),
517 ident,
518 ns,
519 adjusted_parent_scope,
520 if matches!(scope_set, ScopeSet::Late(..)) {
521 Shadowing::Unrestricted
522 } else {
523 Shadowing::Restricted
524 },
525 finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }),
526 ignore_binding,
527 ignore_import,
528 );
529 match binding {
530 Ok(binding) => {
531 if let Some(lint_id) = derive_fallback_lint_id {
532 this.lint_buffer.buffer_lint(
533 PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
534 lint_id,
535 orig_ident.span,
536 BuiltinLintDiag::ProcMacroDeriveResolutionFallback {
537 span: orig_ident.span,
538 ns,
539 ident,
540 },
541 );
542 }
543 let misc_flags = if module == this.graph_root {
544 Flags::MISC_SUGGEST_CRATE
545 } else if module.is_normal() {
546 Flags::MISC_SUGGEST_SELF
547 } else {
548 Flags::empty()
549 };
550 Ok((binding, Flags::MODULE | misc_flags))
551 }
552 Err((Determinacy::Undetermined, Weak::No)) => {
553 return Some(Err(Determinacy::determined(force)));
554 }
555 Err((Determinacy::Undetermined, Weak::Yes)) => {
556 Err(Determinacy::Undetermined)
557 }
558 Err((Determinacy::Determined, _)) => Err(Determinacy::Determined),
559 }
560 }
561 Scope::MacroUsePrelude => {
562 match this.macro_use_prelude.get(&ident.name).cloned() {
563 Some(binding) => Ok((binding, Flags::MISC_FROM_PRELUDE)),
564 None => Err(Determinacy::determined(
565 this.graph_root.unexpanded_invocations.borrow().is_empty(),
566 )),
567 }
568 }
569 Scope::BuiltinAttrs => match this.builtin_attrs_bindings.get(&ident.name) {
570 Some(binding) => Ok((*binding, Flags::empty())),
571 None => Err(Determinacy::Determined),
572 },
573 Scope::ExternPrelude => {
574 match this.extern_prelude_get(ident, finalize.is_some()) {
575 Some(binding) => Ok((binding, Flags::empty())),
576 None => Err(Determinacy::determined(
577 this.graph_root.unexpanded_invocations.borrow().is_empty(),
578 )),
579 }
580 }
581 Scope::ToolPrelude => match this.registered_tool_bindings.get(&ident) {
582 Some(binding) => Ok((*binding, Flags::empty())),
583 None => Err(Determinacy::Determined),
584 },
585 Scope::StdLibPrelude => {
586 let mut result = Err(Determinacy::Determined);
587 if let Some(prelude) = this.prelude
588 && let Ok(binding) = this.resolve_ident_in_module_unadjusted(
589 ModuleOrUniformRoot::Module(prelude),
590 ident,
591 ns,
592 parent_scope,
593 Shadowing::Unrestricted,
594 None,
595 ignore_binding,
596 ignore_import,
597 )
598 && (matches!(use_prelude, UsePrelude::Yes)
599 || this.is_builtin_macro(binding.res()))
600 {
601 result = Ok((binding, Flags::MISC_FROM_PRELUDE));
602 }
603
604 result
605 }
606 Scope::BuiltinTypes => match this.builtin_types_bindings.get(&ident.name) {
607 Some(binding) => {
608 if matches!(ident.name, sym::f16)
609 && !this.tcx.features().f16()
610 && !ident.span.allows_unstable(sym::f16)
611 && finalize.is_some()
612 && innermost_result.is_none()
613 {
614 feature_err(
615 this.tcx.sess,
616 sym::f16,
617 ident.span,
618 "the type `f16` is unstable",
619 )
620 .emit();
621 }
622 if matches!(ident.name, sym::f128)
623 && !this.tcx.features().f128()
624 && !ident.span.allows_unstable(sym::f128)
625 && finalize.is_some()
626 && innermost_result.is_none()
627 {
628 feature_err(
629 this.tcx.sess,
630 sym::f128,
631 ident.span,
632 "the type `f128` is unstable",
633 )
634 .emit();
635 }
636 Ok((*binding, Flags::empty()))
637 }
638 None => Err(Determinacy::Determined),
639 },
640 };
641
642 match result {
643 Ok((binding, flags))
644 if sub_namespace_match(binding.macro_kind(), macro_kind) =>
645 {
646 if finalize.is_none() || matches!(scope_set, ScopeSet::Late(..)) {
647 return Some(Ok(binding));
648 }
649
650 if let Some((innermost_binding, innermost_flags)) = innermost_result {
651 let (res, innermost_res) = (binding.res(), innermost_binding.res());
653 if res != innermost_res {
654 let is_builtin = |res| {
655 matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Builtin(..)))
656 };
657 let derive_helper =
658 Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
659 let derive_helper_compat =
660 Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat);
661
662 let ambiguity_error_kind = if is_builtin(innermost_res)
663 || is_builtin(res)
664 {
665 Some(AmbiguityKind::BuiltinAttr)
666 } else if innermost_res == derive_helper_compat
667 || res == derive_helper_compat && innermost_res != derive_helper
668 {
669 Some(AmbiguityKind::DeriveHelper)
670 } else if innermost_flags.contains(Flags::MACRO_RULES)
671 && flags.contains(Flags::MODULE)
672 && !this.disambiguate_macro_rules_vs_modularized(
673 innermost_binding,
674 binding,
675 )
676 || flags.contains(Flags::MACRO_RULES)
677 && innermost_flags.contains(Flags::MODULE)
678 && !this.disambiguate_macro_rules_vs_modularized(
679 binding,
680 innermost_binding,
681 )
682 {
683 Some(AmbiguityKind::MacroRulesVsModularized)
684 } else if innermost_binding.is_glob_import() {
685 Some(AmbiguityKind::GlobVsOuter)
686 } else if innermost_binding
687 .may_appear_after(parent_scope.expansion, binding)
688 {
689 Some(AmbiguityKind::MoreExpandedVsOuter)
690 } else {
691 None
692 };
693 if let Some(kind) = ambiguity_error_kind {
694 let misc = |f: Flags| {
695 if f.contains(Flags::MISC_SUGGEST_CRATE) {
696 AmbiguityErrorMisc::SuggestCrate
697 } else if f.contains(Flags::MISC_SUGGEST_SELF) {
698 AmbiguityErrorMisc::SuggestSelf
699 } else if f.contains(Flags::MISC_FROM_PRELUDE) {
700 AmbiguityErrorMisc::FromPrelude
701 } else {
702 AmbiguityErrorMisc::None
703 }
704 };
705 this.ambiguity_errors.push(AmbiguityError {
706 kind,
707 ident: orig_ident,
708 b1: innermost_binding,
709 b2: binding,
710 warning: false,
711 misc1: misc(innermost_flags),
712 misc2: misc(flags),
713 });
714 return Some(Ok(innermost_binding));
715 }
716 }
717 } else {
718 innermost_result = Some((binding, flags));
720 }
721 }
722 Ok(..) | Err(Determinacy::Determined) => {}
723 Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined,
724 }
725
726 None
727 },
728 );
729
730 if let Some(break_result) = break_result {
731 return break_result;
732 }
733
734 if let Some((binding, _)) = innermost_result {
736 return Ok(binding);
737 }
738
739 Err(Determinacy::determined(determinacy == Determinacy::Determined || force))
740 }
741
742 #[instrument(level = "debug", skip(self))]
743 pub(crate) fn maybe_resolve_ident_in_module(
744 &mut self,
745 module: ModuleOrUniformRoot<'ra>,
746 ident: Ident,
747 ns: Namespace,
748 parent_scope: &ParentScope<'ra>,
749 ignore_import: Option<Import<'ra>>,
750 ) -> Result<NameBinding<'ra>, Determinacy> {
751 self.resolve_ident_in_module(module, ident, ns, parent_scope, None, None, ignore_import)
752 .map_err(|(determinacy, _)| determinacy)
753 }
754
755 #[instrument(level = "debug", skip(self))]
756 pub(crate) fn resolve_ident_in_module(
757 &mut self,
758 module: ModuleOrUniformRoot<'ra>,
759 mut ident: Ident,
760 ns: Namespace,
761 parent_scope: &ParentScope<'ra>,
762 finalize: Option<Finalize>,
763 ignore_binding: Option<NameBinding<'ra>>,
764 ignore_import: Option<Import<'ra>>,
765 ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
766 let tmp_parent_scope;
767 let mut adjusted_parent_scope = parent_scope;
768 match module {
769 ModuleOrUniformRoot::Module(m) => {
770 if let Some(def) = ident.span.normalize_to_macros_2_0_and_adjust(m.expansion) {
771 tmp_parent_scope =
772 ParentScope { module: self.expn_def_scope(def), ..*parent_scope };
773 adjusted_parent_scope = &tmp_parent_scope;
774 }
775 }
776 ModuleOrUniformRoot::ExternPrelude => {
777 ident.span.normalize_to_macros_2_0_and_adjust(ExpnId::root());
778 }
779 ModuleOrUniformRoot::CrateRootAndExternPrelude | ModuleOrUniformRoot::CurrentScope => {
780 }
782 }
783 self.resolve_ident_in_module_unadjusted(
784 module,
785 ident,
786 ns,
787 adjusted_parent_scope,
788 Shadowing::Unrestricted,
789 finalize,
790 ignore_binding,
791 ignore_import,
792 )
793 }
794
795 #[instrument(level = "debug", skip(self))]
798 fn resolve_ident_in_module_unadjusted(
799 &mut self,
800 module: ModuleOrUniformRoot<'ra>,
801 ident: Ident,
802 ns: Namespace,
803 parent_scope: &ParentScope<'ra>,
804 shadowing: Shadowing,
805 finalize: Option<Finalize>,
806 ignore_binding: Option<NameBinding<'ra>>,
809 ignore_import: Option<Import<'ra>>,
810 ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
811 let module = match module {
812 ModuleOrUniformRoot::Module(module) => module,
813 ModuleOrUniformRoot::CrateRootAndExternPrelude => {
814 assert_eq!(shadowing, Shadowing::Unrestricted);
815 let binding = self.early_resolve_ident_in_lexical_scope(
816 ident,
817 ScopeSet::AbsolutePath(ns),
818 parent_scope,
819 finalize,
820 finalize.is_some(),
821 ignore_binding,
822 ignore_import,
823 );
824 return binding.map_err(|determinacy| (determinacy, Weak::No));
825 }
826 ModuleOrUniformRoot::ExternPrelude => {
827 assert_eq!(shadowing, Shadowing::Unrestricted);
828 return if ns != TypeNS {
829 Err((Determined, Weak::No))
830 } else if let Some(binding) = self.extern_prelude_get(ident, finalize.is_some()) {
831 Ok(binding)
832 } else if !self.graph_root.unexpanded_invocations.borrow().is_empty() {
833 Err((Undetermined, Weak::No))
835 } else {
836 Err((Determined, Weak::No))
837 };
838 }
839 ModuleOrUniformRoot::CurrentScope => {
840 assert_eq!(shadowing, Shadowing::Unrestricted);
841 if ns == TypeNS {
842 if ident.name == kw::Crate || ident.name == kw::DollarCrate {
843 let module = self.resolve_crate_root(ident);
844 return Ok(module.self_binding.unwrap());
845 } else if ident.name == kw::Super || ident.name == kw::SelfLower {
846 }
850 }
851
852 let binding = self.early_resolve_ident_in_lexical_scope(
853 ident,
854 ScopeSet::All(ns),
855 parent_scope,
856 finalize,
857 finalize.is_some(),
858 ignore_binding,
859 ignore_import,
860 );
861 return binding.map_err(|determinacy| (determinacy, Weak::No));
862 }
863 };
864
865 let key = BindingKey::new(ident, ns);
866 let resolution =
867 self.resolution(module, key).try_borrow_mut().map_err(|_| (Determined, Weak::No))?; let binding = [resolution.non_glob_binding, resolution.glob_binding]
874 .into_iter()
875 .find_map(|binding| if binding == ignore_binding { None } else { binding });
876
877 if let Some(finalize) = finalize {
878 return self.finalize_module_binding(
879 ident,
880 binding,
881 if resolution.non_glob_binding.is_some() { resolution.glob_binding } else { None },
882 parent_scope,
883 finalize,
884 shadowing,
885 );
886 }
887
888 let check_usable = |this: &Self, binding: NameBinding<'ra>| {
889 let usable = this.is_accessible_from(binding.vis, parent_scope.module);
890 if usable { Ok(binding) } else { Err((Determined, Weak::No)) }
891 };
892
893 if let Some(binding) = binding
895 && !binding.is_glob_import()
896 {
897 return check_usable(self, binding);
898 }
899
900 if self.single_import_can_define_name(
905 &resolution,
906 binding,
907 ns,
908 ignore_import,
909 ignore_binding,
910 parent_scope,
911 ) {
912 return Err((Undetermined, Weak::No));
913 }
914
915 if let Some(binding) = binding {
928 if binding.determined() || ns == MacroNS || shadowing == Shadowing::Restricted {
929 return check_usable(self, binding);
930 } else {
931 return Err((Undetermined, Weak::No));
932 }
933 }
934
935 if !module.unexpanded_invocations.borrow().is_empty() {
946 return Err((Undetermined, Weak::Yes));
947 }
948
949 for glob_import in module.globs.borrow().iter() {
952 if ignore_import == Some(*glob_import) {
953 continue;
954 }
955 if !self.is_accessible_from(glob_import.vis, parent_scope.module) {
956 continue;
957 }
958 let module = match glob_import.imported_module.get() {
959 Some(ModuleOrUniformRoot::Module(module)) => module,
960 Some(_) => continue,
961 None => return Err((Undetermined, Weak::Yes)),
962 };
963 let tmp_parent_scope;
964 let (mut adjusted_parent_scope, mut ident) =
965 (parent_scope, ident.normalize_to_macros_2_0());
966 match ident.span.glob_adjust(module.expansion, glob_import.span) {
967 Some(Some(def)) => {
968 tmp_parent_scope =
969 ParentScope { module: self.expn_def_scope(def), ..*parent_scope };
970 adjusted_parent_scope = &tmp_parent_scope;
971 }
972 Some(None) => {}
973 None => continue,
974 };
975 let result = self.resolve_ident_in_module_unadjusted(
976 ModuleOrUniformRoot::Module(module),
977 ident,
978 ns,
979 adjusted_parent_scope,
980 Shadowing::Unrestricted,
981 None,
982 ignore_binding,
983 ignore_import,
984 );
985
986 match result {
987 Err((Determined, _)) => continue,
988 Ok(binding)
989 if !self.is_accessible_from(binding.vis, glob_import.parent_scope.module) =>
990 {
991 continue;
992 }
993 Ok(_) | Err((Undetermined, _)) => return Err((Undetermined, Weak::Yes)),
994 }
995 }
996
997 Err((Determined, Weak::No))
999 }
1000
1001 fn finalize_module_binding(
1002 &mut self,
1003 ident: Ident,
1004 binding: Option<NameBinding<'ra>>,
1005 shadowed_glob: Option<NameBinding<'ra>>,
1006 parent_scope: &ParentScope<'ra>,
1007 finalize: Finalize,
1008 shadowing: Shadowing,
1009 ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
1010 let Finalize { path_span, report_private, used, root_span, .. } = finalize;
1011
1012 let Some(binding) = binding else {
1013 return Err((Determined, Weak::No));
1014 };
1015
1016 if !self.is_accessible_from(binding.vis, parent_scope.module) {
1017 if report_private {
1018 self.privacy_errors.push(PrivacyError {
1019 ident,
1020 binding,
1021 dedup_span: path_span,
1022 outermost_res: None,
1023 parent_scope: *parent_scope,
1024 single_nested: path_span != root_span,
1025 });
1026 } else {
1027 return Err((Determined, Weak::No));
1028 }
1029 }
1030
1031 if let Some(shadowed_glob) = shadowed_glob
1033 && shadowing == Shadowing::Restricted
1034 && binding.expansion != LocalExpnId::ROOT
1035 && binding.res() != shadowed_glob.res()
1036 {
1037 self.ambiguity_errors.push(AmbiguityError {
1038 kind: AmbiguityKind::GlobVsExpanded,
1039 ident,
1040 b1: binding,
1041 b2: shadowed_glob,
1042 warning: false,
1043 misc1: AmbiguityErrorMisc::None,
1044 misc2: AmbiguityErrorMisc::None,
1045 });
1046 }
1047
1048 if shadowing == Shadowing::Unrestricted
1049 && binding.expansion != LocalExpnId::ROOT
1050 && let NameBindingKind::Import { import, .. } = binding.kind
1051 && matches!(import.kind, ImportKind::MacroExport)
1052 {
1053 self.macro_expanded_macro_export_errors.insert((path_span, binding.span));
1054 }
1055
1056 self.record_use(ident, binding, used);
1057 return Ok(binding);
1058 }
1059
1060 fn single_import_can_define_name(
1063 &mut self,
1064 resolution: &NameResolution<'ra>,
1065 binding: Option<NameBinding<'ra>>,
1066 ns: Namespace,
1067 ignore_import: Option<Import<'ra>>,
1068 ignore_binding: Option<NameBinding<'ra>>,
1069 parent_scope: &ParentScope<'ra>,
1070 ) -> bool {
1071 for single_import in &resolution.single_imports {
1072 if ignore_import == Some(*single_import) {
1073 continue;
1074 }
1075 if !self.is_accessible_from(single_import.vis, parent_scope.module) {
1076 continue;
1077 }
1078 if let Some(ignored) = ignore_binding
1079 && let NameBindingKind::Import { import, .. } = ignored.kind
1080 && import == *single_import
1081 {
1082 continue;
1083 }
1084
1085 let Some(module) = single_import.imported_module.get() else {
1086 return true;
1087 };
1088 let ImportKind::Single { source, target, bindings, .. } = &single_import.kind else {
1089 unreachable!();
1090 };
1091 if source != target {
1092 if bindings.iter().all(|binding| binding.get().binding().is_none()) {
1093 return true;
1094 } else if bindings[ns].get().binding().is_none() && binding.is_some() {
1095 return true;
1096 }
1097 }
1098
1099 match self.resolve_ident_in_module(
1100 module,
1101 *source,
1102 ns,
1103 &single_import.parent_scope,
1104 None,
1105 ignore_binding,
1106 ignore_import,
1107 ) {
1108 Err((Determined, _)) => continue,
1109 Ok(binding)
1110 if !self.is_accessible_from(binding.vis, single_import.parent_scope.module) =>
1111 {
1112 continue;
1113 }
1114 Ok(_) | Err((Undetermined, _)) => {
1115 return true;
1116 }
1117 }
1118 }
1119
1120 false
1121 }
1122
1123 #[instrument(level = "debug", skip(self, all_ribs))]
1125 fn validate_res_from_ribs(
1126 &mut self,
1127 rib_index: usize,
1128 rib_ident: Ident,
1129 mut res: Res,
1130 finalize: Option<Span>,
1131 original_rib_ident_def: Ident,
1132 all_ribs: &[Rib<'ra>],
1133 ) -> Res {
1134 debug!("validate_res_from_ribs({:?})", res);
1135 let ribs = &all_ribs[rib_index + 1..];
1136
1137 if let RibKind::ForwardGenericParamBan(reason) = all_ribs[rib_index].kind {
1140 if let Some(span) = finalize {
1141 let res_error = if rib_ident.name == kw::SelfUpper {
1142 ResolutionError::ForwardDeclaredSelf(reason)
1143 } else {
1144 ResolutionError::ForwardDeclaredGenericParam(rib_ident.name, reason)
1145 };
1146 self.report_error(span, res_error);
1147 }
1148 assert_eq!(res, Res::Err);
1149 return Res::Err;
1150 }
1151
1152 match res {
1153 Res::Local(_) => {
1154 use ResolutionError::*;
1155 let mut res_err = None;
1156
1157 for rib in ribs {
1158 match rib.kind {
1159 RibKind::Normal
1160 | RibKind::FnOrCoroutine
1161 | RibKind::Module(..)
1162 | RibKind::MacroDefinition(..)
1163 | RibKind::ForwardGenericParamBan(_) => {
1164 }
1166 RibKind::Item(..) | RibKind::AssocItem => {
1167 if let Some(span) = finalize {
1171 res_err = Some((span, CannotCaptureDynamicEnvironmentInFnItem));
1176 }
1177 }
1178 RibKind::ConstantItem(_, item) => {
1179 if let Some(span) = finalize {
1181 let (span, resolution_error) = match item {
1182 None if rib_ident.name == kw::SelfLower => {
1183 (span, LowercaseSelf)
1184 }
1185 None => {
1186 let sm = self.tcx.sess.source_map();
1192 let type_span = match sm.span_look_ahead(
1193 original_rib_ident_def.span,
1194 ":",
1195 None,
1196 ) {
1197 None => {
1198 Some(original_rib_ident_def.span.shrink_to_hi())
1199 }
1200 Some(_) => None,
1201 };
1202 (
1203 rib_ident.span,
1204 AttemptToUseNonConstantValueInConstant {
1205 ident: original_rib_ident_def,
1206 suggestion: "const",
1207 current: "let",
1208 type_span,
1209 },
1210 )
1211 }
1212 Some((ident, kind)) => (
1213 span,
1214 AttemptToUseNonConstantValueInConstant {
1215 ident,
1216 suggestion: "let",
1217 current: kind.as_str(),
1218 type_span: None,
1219 },
1220 ),
1221 };
1222 self.report_error(span, resolution_error);
1223 }
1224 return Res::Err;
1225 }
1226 RibKind::ConstParamTy => {
1227 if let Some(span) = finalize {
1228 self.report_error(
1229 span,
1230 ParamInTyOfConstParam { name: rib_ident.name },
1231 );
1232 }
1233 return Res::Err;
1234 }
1235 RibKind::InlineAsmSym => {
1236 if let Some(span) = finalize {
1237 self.report_error(span, InvalidAsmSym);
1238 }
1239 return Res::Err;
1240 }
1241 }
1242 }
1243 if let Some((span, res_err)) = res_err {
1244 self.report_error(span, res_err);
1245 return Res::Err;
1246 }
1247 }
1248 Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {
1249 for rib in ribs {
1250 let (has_generic_params, def_kind) = match rib.kind {
1251 RibKind::Normal
1252 | RibKind::FnOrCoroutine
1253 | RibKind::Module(..)
1254 | RibKind::MacroDefinition(..)
1255 | RibKind::InlineAsmSym
1256 | RibKind::AssocItem
1257 | RibKind::ForwardGenericParamBan(_) => {
1258 continue;
1260 }
1261
1262 RibKind::ConstParamTy => {
1263 if !self.tcx.features().generic_const_parameter_types() {
1264 if let Some(span) = finalize {
1265 self.report_error(
1266 span,
1267 ResolutionError::ParamInTyOfConstParam {
1268 name: rib_ident.name,
1269 },
1270 );
1271 }
1272 return Res::Err;
1273 } else {
1274 continue;
1275 }
1276 }
1277
1278 RibKind::ConstantItem(trivial, _) => {
1279 if let ConstantHasGenerics::No(cause) = trivial {
1280 if let Res::SelfTyAlias {
1285 alias_to: def,
1286 forbid_generic: _,
1287 is_trait_impl,
1288 } = res
1289 {
1290 res = Res::SelfTyAlias {
1291 alias_to: def,
1292 forbid_generic: true,
1293 is_trait_impl,
1294 }
1295 } else {
1296 if let Some(span) = finalize {
1297 let error = match cause {
1298 NoConstantGenericsReason::IsEnumDiscriminant => {
1299 ResolutionError::ParamInEnumDiscriminant {
1300 name: rib_ident.name,
1301 param_kind: ParamKindInEnumDiscriminant::Type,
1302 }
1303 }
1304 NoConstantGenericsReason::NonTrivialConstArg => {
1305 ResolutionError::ParamInNonTrivialAnonConst {
1306 name: rib_ident.name,
1307 param_kind:
1308 ParamKindInNonTrivialAnonConst::Type,
1309 }
1310 }
1311 };
1312 let _: ErrorGuaranteed = self.report_error(span, error);
1313 }
1314
1315 return Res::Err;
1316 }
1317 }
1318
1319 continue;
1320 }
1321
1322 RibKind::Item(has_generic_params, def_kind) => {
1324 (has_generic_params, def_kind)
1325 }
1326 };
1327
1328 if let Some(span) = finalize {
1329 self.report_error(
1330 span,
1331 ResolutionError::GenericParamsFromOuterItem(
1332 res,
1333 has_generic_params,
1334 def_kind,
1335 ),
1336 );
1337 }
1338 return Res::Err;
1339 }
1340 }
1341 Res::Def(DefKind::ConstParam, _) => {
1342 for rib in ribs {
1343 let (has_generic_params, def_kind) = match rib.kind {
1344 RibKind::Normal
1345 | RibKind::FnOrCoroutine
1346 | RibKind::Module(..)
1347 | RibKind::MacroDefinition(..)
1348 | RibKind::InlineAsmSym
1349 | RibKind::AssocItem
1350 | RibKind::ForwardGenericParamBan(_) => continue,
1351
1352 RibKind::ConstParamTy => {
1353 if !self.tcx.features().generic_const_parameter_types() {
1354 if let Some(span) = finalize {
1355 self.report_error(
1356 span,
1357 ResolutionError::ParamInTyOfConstParam {
1358 name: rib_ident.name,
1359 },
1360 );
1361 }
1362 return Res::Err;
1363 } else {
1364 continue;
1365 }
1366 }
1367
1368 RibKind::ConstantItem(trivial, _) => {
1369 if let ConstantHasGenerics::No(cause) = trivial {
1370 if let Some(span) = finalize {
1371 let error = match cause {
1372 NoConstantGenericsReason::IsEnumDiscriminant => {
1373 ResolutionError::ParamInEnumDiscriminant {
1374 name: rib_ident.name,
1375 param_kind: ParamKindInEnumDiscriminant::Const,
1376 }
1377 }
1378 NoConstantGenericsReason::NonTrivialConstArg => {
1379 ResolutionError::ParamInNonTrivialAnonConst {
1380 name: rib_ident.name,
1381 param_kind: ParamKindInNonTrivialAnonConst::Const {
1382 name: rib_ident.name,
1383 },
1384 }
1385 }
1386 };
1387 self.report_error(span, error);
1388 }
1389
1390 return Res::Err;
1391 }
1392
1393 continue;
1394 }
1395
1396 RibKind::Item(has_generic_params, def_kind) => {
1397 (has_generic_params, def_kind)
1398 }
1399 };
1400
1401 if let Some(span) = finalize {
1403 self.report_error(
1404 span,
1405 ResolutionError::GenericParamsFromOuterItem(
1406 res,
1407 has_generic_params,
1408 def_kind,
1409 ),
1410 );
1411 }
1412 return Res::Err;
1413 }
1414 }
1415 _ => {}
1416 }
1417
1418 res
1419 }
1420
1421 #[instrument(level = "debug", skip(self))]
1422 pub(crate) fn maybe_resolve_path(
1423 &mut self,
1424 path: &[Segment],
1425 opt_ns: Option<Namespace>, parent_scope: &ParentScope<'ra>,
1427 ignore_import: Option<Import<'ra>>,
1428 ) -> PathResult<'ra> {
1429 self.resolve_path_with_ribs(path, opt_ns, parent_scope, None, None, None, ignore_import)
1430 }
1431
1432 #[instrument(level = "debug", skip(self))]
1433 pub(crate) fn resolve_path(
1434 &mut self,
1435 path: &[Segment],
1436 opt_ns: Option<Namespace>, parent_scope: &ParentScope<'ra>,
1438 finalize: Option<Finalize>,
1439 ignore_binding: Option<NameBinding<'ra>>,
1440 ignore_import: Option<Import<'ra>>,
1441 ) -> PathResult<'ra> {
1442 self.resolve_path_with_ribs(
1443 path,
1444 opt_ns,
1445 parent_scope,
1446 finalize,
1447 None,
1448 ignore_binding,
1449 ignore_import,
1450 )
1451 }
1452
1453 pub(crate) fn resolve_path_with_ribs(
1454 &mut self,
1455 path: &[Segment],
1456 opt_ns: Option<Namespace>, parent_scope: &ParentScope<'ra>,
1458 finalize: Option<Finalize>,
1459 ribs: Option<&PerNS<Vec<Rib<'ra>>>>,
1460 ignore_binding: Option<NameBinding<'ra>>,
1461 ignore_import: Option<Import<'ra>>,
1462 ) -> PathResult<'ra> {
1463 let mut module = None;
1464 let mut module_had_parse_errors = false;
1465 let mut allow_super = true;
1466 let mut second_binding = None;
1467
1468 let privacy_errors_len = self.privacy_errors.len();
1470
1471 for (segment_idx, &Segment { ident, id, .. }) in path.iter().enumerate() {
1472 debug!("resolve_path ident {} {:?} {:?}", segment_idx, ident, id);
1473 let record_segment_res = |this: &mut Self, res| {
1474 if finalize.is_some()
1475 && let Some(id) = id
1476 && !this.partial_res_map.contains_key(&id)
1477 {
1478 assert!(id != ast::DUMMY_NODE_ID, "Trying to resolve dummy id");
1479 this.record_partial_res(id, PartialRes::new(res));
1480 }
1481 };
1482
1483 let is_last = segment_idx + 1 == path.len();
1484 let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };
1485 let name = ident.name;
1486
1487 allow_super &= ns == TypeNS && (name == kw::SelfLower || name == kw::Super);
1488
1489 if ns == TypeNS {
1490 if allow_super && name == kw::Super {
1491 let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();
1492 let self_module = match segment_idx {
1493 0 => Some(self.resolve_self(&mut ctxt, parent_scope.module)),
1494 _ => match module {
1495 Some(ModuleOrUniformRoot::Module(module)) => Some(module),
1496 _ => None,
1497 },
1498 };
1499 if let Some(self_module) = self_module
1500 && let Some(parent) = self_module.parent
1501 {
1502 module =
1503 Some(ModuleOrUniformRoot::Module(self.resolve_self(&mut ctxt, parent)));
1504 continue;
1505 }
1506 return PathResult::failed(
1507 ident,
1508 false,
1509 finalize.is_some(),
1510 module_had_parse_errors,
1511 module,
1512 || ("there are too many leading `super` keywords".to_string(), None),
1513 );
1514 }
1515 if segment_idx == 0 {
1516 if name == kw::SelfLower {
1517 let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();
1518 let self_mod = self.resolve_self(&mut ctxt, parent_scope.module);
1519 if let Some(res) = self_mod.res() {
1520 record_segment_res(self, res);
1521 }
1522 module = Some(ModuleOrUniformRoot::Module(self_mod));
1523 continue;
1524 }
1525 if name == kw::PathRoot && ident.span.at_least_rust_2018() {
1526 module = Some(ModuleOrUniformRoot::ExternPrelude);
1527 continue;
1528 }
1529 if name == kw::PathRoot
1530 && ident.span.is_rust_2015()
1531 && self.tcx.sess.at_least_rust_2018()
1532 {
1533 module = Some(ModuleOrUniformRoot::CrateRootAndExternPrelude);
1535 continue;
1536 }
1537 if name == kw::PathRoot || name == kw::Crate || name == kw::DollarCrate {
1538 let crate_root = self.resolve_crate_root(ident);
1540 if let Some(res) = crate_root.res() {
1541 record_segment_res(self, res);
1542 }
1543 module = Some(ModuleOrUniformRoot::Module(crate_root));
1544 continue;
1545 }
1546 }
1547 }
1548
1549 if ident.is_path_segment_keyword() && segment_idx != 0 {
1551 return PathResult::failed(
1552 ident,
1553 false,
1554 finalize.is_some(),
1555 module_had_parse_errors,
1556 module,
1557 || {
1558 let name_str = if name == kw::PathRoot {
1559 "crate root".to_string()
1560 } else {
1561 format!("`{name}`")
1562 };
1563 let label = if segment_idx == 1 && path[0].ident.name == kw::PathRoot {
1564 format!("global paths cannot start with {name_str}")
1565 } else {
1566 format!("{name_str} in paths can only be used in start position")
1567 };
1568 (label, None)
1569 },
1570 );
1571 }
1572
1573 let binding = if let Some(module) = module {
1574 self.resolve_ident_in_module(
1575 module,
1576 ident,
1577 ns,
1578 parent_scope,
1579 finalize,
1580 ignore_binding,
1581 ignore_import,
1582 )
1583 .map_err(|(determinacy, _)| determinacy)
1584 } else if let Some(ribs) = ribs
1585 && let Some(TypeNS | ValueNS) = opt_ns
1586 {
1587 assert!(ignore_import.is_none());
1588 match self.resolve_ident_in_lexical_scope(
1589 ident,
1590 ns,
1591 parent_scope,
1592 finalize,
1593 &ribs[ns],
1594 ignore_binding,
1595 ) {
1596 Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
1598 Some(LexicalScopeBinding::Res(res)) => {
1600 record_segment_res(self, res);
1601 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1602 res,
1603 path.len() - 1,
1604 ));
1605 }
1606 _ => Err(Determinacy::determined(finalize.is_some())),
1607 }
1608 } else {
1609 self.early_resolve_ident_in_lexical_scope(
1610 ident,
1611 ScopeSet::All(ns),
1612 parent_scope,
1613 finalize,
1614 finalize.is_some(),
1615 ignore_binding,
1616 ignore_import,
1617 )
1618 };
1619
1620 match binding {
1621 Ok(binding) => {
1622 if segment_idx == 1 {
1623 second_binding = Some(binding);
1624 }
1625 let res = binding.res();
1626
1627 for error in &mut self.privacy_errors[privacy_errors_len..] {
1631 error.outermost_res = Some((res, ident));
1632 }
1633
1634 let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(res);
1635 if let Some(def_id) = binding.res().module_like_def_id() {
1636 if self.mods_with_parse_errors.contains(&def_id) {
1637 module_had_parse_errors = true;
1638 }
1639 module = Some(ModuleOrUniformRoot::Module(self.expect_module(def_id)));
1640 record_segment_res(self, res);
1641 } else if res == Res::ToolMod && !is_last && opt_ns.is_some() {
1642 if binding.is_import() {
1643 self.dcx().emit_err(errors::ToolModuleImported {
1644 span: ident.span,
1645 import: binding.span,
1646 });
1647 }
1648 let res = Res::NonMacroAttr(NonMacroAttrKind::Tool);
1649 return PathResult::NonModule(PartialRes::new(res));
1650 } else if res == Res::Err {
1651 return PathResult::NonModule(PartialRes::new(Res::Err));
1652 } else if opt_ns.is_some() && (is_last || maybe_assoc) {
1653 self.lint_if_path_starts_with_module(finalize, path, second_binding);
1654 record_segment_res(self, res);
1655 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1656 res,
1657 path.len() - segment_idx - 1,
1658 ));
1659 } else {
1660 return PathResult::failed(
1661 ident,
1662 is_last,
1663 finalize.is_some(),
1664 module_had_parse_errors,
1665 module,
1666 || {
1667 let label = format!(
1668 "`{ident}` is {} {}, not a module",
1669 res.article(),
1670 res.descr()
1671 );
1672 (label, None)
1673 },
1674 );
1675 }
1676 }
1677 Err(Undetermined) => return PathResult::Indeterminate,
1678 Err(Determined) => {
1679 if let Some(ModuleOrUniformRoot::Module(module)) = module
1680 && opt_ns.is_some()
1681 && !module.is_normal()
1682 {
1683 return PathResult::NonModule(PartialRes::with_unresolved_segments(
1684 module.res().unwrap(),
1685 path.len() - segment_idx,
1686 ));
1687 }
1688
1689 return PathResult::failed(
1690 ident,
1691 is_last,
1692 finalize.is_some(),
1693 module_had_parse_errors,
1694 module,
1695 || {
1696 self.report_path_resolution_error(
1697 path,
1698 opt_ns,
1699 parent_scope,
1700 ribs,
1701 ignore_binding,
1702 ignore_import,
1703 module,
1704 segment_idx,
1705 ident,
1706 )
1707 },
1708 );
1709 }
1710 }
1711 }
1712
1713 self.lint_if_path_starts_with_module(finalize, path, second_binding);
1714
1715 PathResult::Module(match module {
1716 Some(module) => module,
1717 None if path.is_empty() => ModuleOrUniformRoot::CurrentScope,
1718 _ => bug!("resolve_path: non-empty path `{:?}` has no module", path),
1719 })
1720 }
1721}