Skip to content

Commit 47edfd3

Browse files
committed
resolve: Move ambiguity detection in resolve_ident_in_scope_set into a separate function
1 parent 6ca6302 commit 47edfd3

File tree

1 file changed

+95
-80
lines changed

1 file changed

+95
-80
lines changed

compiler/rustc_resolve/src/ident.rs

Lines changed: 95 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -474,86 +474,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
474474

475475
if let Some((innermost_binding, innermost_flags)) = innermost_result {
476476
// Found another solution, if the first one was "weak", report an error.
477-
let (res, innermost_res) = (binding.res(), innermost_binding.res());
478-
if res != innermost_res {
479-
let is_builtin = |res| {
480-
matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Builtin(..)))
481-
};
482-
let derive_helper =
483-
Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
484-
let derive_helper_compat =
485-
Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat);
486-
487-
let ambiguity_error_kind = if is_builtin(innermost_res)
488-
|| is_builtin(res)
489-
{
490-
Some(AmbiguityKind::BuiltinAttr)
491-
} else if innermost_res == derive_helper_compat
492-
|| res == derive_helper_compat && innermost_res != derive_helper
493-
{
494-
Some(AmbiguityKind::DeriveHelper)
495-
} else if innermost_flags.contains(Flags::MACRO_RULES)
496-
&& flags.contains(Flags::MODULE)
497-
&& !this.disambiguate_macro_rules_vs_modularized(
498-
innermost_binding,
499-
binding,
500-
)
501-
{
502-
Some(AmbiguityKind::MacroRulesVsModularized)
503-
} else if flags.contains(Flags::MACRO_RULES)
504-
&& innermost_flags.contains(Flags::MODULE)
505-
{
506-
// should be impossible because of visitation order in
507-
// visit_scopes
508-
//
509-
// we visit all macro_rules scopes (e.g. textual scope macros)
510-
// before we visit any modules (e.g. path-based scope macros)
511-
span_bug!(
512-
orig_ident.span,
513-
"ambiguous scoped macro resolutions with path-based \
514-
scope resolution as first candidate"
515-
)
516-
} else if innermost_binding.is_glob_import() {
517-
Some(AmbiguityKind::GlobVsOuter)
518-
} else if innermost_binding
519-
.may_appear_after(parent_scope.expansion, binding)
520-
{
521-
Some(AmbiguityKind::MoreExpandedVsOuter)
522-
} else {
523-
None
524-
};
525-
// Skip ambiguity errors for extern flag bindings "overridden"
526-
// by extern item bindings.
527-
// FIXME: Remove with lang team approval.
528-
let issue_145575_hack = Some(binding)
529-
== extern_prelude_flag_binding
530-
&& extern_prelude_item_binding.is_some()
531-
&& extern_prelude_item_binding != Some(innermost_binding);
532-
if let Some(kind) = ambiguity_error_kind
533-
&& !issue_145575_hack
534-
{
535-
let misc = |f: Flags| {
536-
if f.contains(Flags::MISC_SUGGEST_CRATE) {
537-
AmbiguityErrorMisc::SuggestCrate
538-
} else if f.contains(Flags::MISC_SUGGEST_SELF) {
539-
AmbiguityErrorMisc::SuggestSelf
540-
} else if f.contains(Flags::MISC_FROM_PRELUDE) {
541-
AmbiguityErrorMisc::FromPrelude
542-
} else {
543-
AmbiguityErrorMisc::None
544-
}
545-
};
546-
this.get_mut().ambiguity_errors.push(AmbiguityError {
547-
kind,
548-
ident: orig_ident,
549-
b1: innermost_binding,
550-
b2: binding,
551-
warning: false,
552-
misc1: misc(innermost_flags),
553-
misc2: misc(flags),
554-
});
555-
return ControlFlow::Break(Ok(innermost_binding));
556-
}
477+
if this.get_mut().maybe_push_ambiguity(
478+
orig_ident,
479+
parent_scope,
480+
binding,
481+
innermost_binding,
482+
flags,
483+
innermost_flags,
484+
extern_prelude_item_binding,
485+
extern_prelude_flag_binding,
486+
) {
487+
return ControlFlow::Break(Ok(innermost_binding));
557488
}
558489
} else {
559490
// Found the first solution.
@@ -788,6 +719,90 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
788719
ControlFlow::Continue(ret)
789720
}
790721

722+
fn maybe_push_ambiguity(
723+
&mut self,
724+
orig_ident: Ident,
725+
parent_scope: &ParentScope<'ra>,
726+
binding: NameBinding<'ra>,
727+
innermost_binding: NameBinding<'ra>,
728+
flags: Flags,
729+
innermost_flags: Flags,
730+
extern_prelude_item_binding: Option<NameBinding<'ra>>,
731+
extern_prelude_flag_binding: Option<NameBinding<'ra>>,
732+
) -> bool {
733+
let (res, innermost_res) = (binding.res(), innermost_binding.res());
734+
if res == innermost_res {
735+
return false;
736+
}
737+
738+
let is_builtin = |res| matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Builtin(..)));
739+
let derive_helper = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
740+
let derive_helper_compat = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat);
741+
742+
let ambiguity_error_kind = if is_builtin(innermost_res) || is_builtin(res) {
743+
Some(AmbiguityKind::BuiltinAttr)
744+
} else if innermost_res == derive_helper_compat
745+
|| res == derive_helper_compat && innermost_res != derive_helper
746+
{
747+
Some(AmbiguityKind::DeriveHelper)
748+
} else if innermost_flags.contains(Flags::MACRO_RULES)
749+
&& flags.contains(Flags::MODULE)
750+
&& !self.disambiguate_macro_rules_vs_modularized(innermost_binding, binding)
751+
{
752+
Some(AmbiguityKind::MacroRulesVsModularized)
753+
} else if flags.contains(Flags::MACRO_RULES) && innermost_flags.contains(Flags::MODULE) {
754+
// should be impossible because of visitation order in
755+
// visit_scopes
756+
//
757+
// we visit all macro_rules scopes (e.g. textual scope macros)
758+
// before we visit any modules (e.g. path-based scope macros)
759+
span_bug!(
760+
orig_ident.span,
761+
"ambiguous scoped macro resolutions with path-based \
762+
scope resolution as first candidate"
763+
)
764+
} else if innermost_binding.is_glob_import() {
765+
Some(AmbiguityKind::GlobVsOuter)
766+
} else if innermost_binding.may_appear_after(parent_scope.expansion, binding) {
767+
Some(AmbiguityKind::MoreExpandedVsOuter)
768+
} else {
769+
None
770+
};
771+
// Skip ambiguity errors for extern flag bindings "overridden"
772+
// by extern item bindings.
773+
// FIXME: Remove with lang team approval.
774+
let issue_145575_hack = Some(binding) == extern_prelude_flag_binding
775+
&& extern_prelude_item_binding.is_some()
776+
&& extern_prelude_item_binding != Some(innermost_binding);
777+
if let Some(kind) = ambiguity_error_kind
778+
&& !issue_145575_hack
779+
{
780+
let misc = |f: Flags| {
781+
if f.contains(Flags::MISC_SUGGEST_CRATE) {
782+
AmbiguityErrorMisc::SuggestCrate
783+
} else if f.contains(Flags::MISC_SUGGEST_SELF) {
784+
AmbiguityErrorMisc::SuggestSelf
785+
} else if f.contains(Flags::MISC_FROM_PRELUDE) {
786+
AmbiguityErrorMisc::FromPrelude
787+
} else {
788+
AmbiguityErrorMisc::None
789+
}
790+
};
791+
self.ambiguity_errors.push(AmbiguityError {
792+
kind,
793+
ident: orig_ident,
794+
b1: innermost_binding,
795+
b2: binding,
796+
warning: false,
797+
misc1: misc(innermost_flags),
798+
misc2: misc(flags),
799+
});
800+
return true;
801+
}
802+
803+
false
804+
}
805+
791806
#[instrument(level = "debug", skip(self))]
792807
pub(crate) fn maybe_resolve_ident_in_module<'r>(
793808
self: CmResolver<'r, 'ra, 'tcx>,

0 commit comments

Comments
 (0)