Fix: Prevent macro-expanded extern crates from shadowing extern arguments by Delta17920 · Pull Request #149860 · rust-lang/rust (original) (raw)
I think #149855 was actually closer to the right solution than this PR, this PR is just hiding the root issue.
The root issue is that issue_145575_hack swallows legitimate ambiguity errors, it's not surprising that they may result in inconsistent resolutions later.
"inconsistent resolution for an import" ICE is already not reported if ambiguity_errors are non-empty, using dcx().has_errors() would be ok too, even if maybe too blunt.
I guess the most surgical solution would looks something like
diff --git i/compiler/rustc_resolve/src/ident.rs w/compiler/rustc_resolve/src/ident.rs index e38d4370d5d..342c1192090 100644 --- i/compiler/rustc_resolve/src/ident.rs +++ w/compiler/rustc_resolve/src/ident.rs @@ -771,36 +771,38 @@ fn maybe_push_ambiguity( } else { None };
// Skip ambiguity errors for extern flag bindings "overridden"// by extern item bindings.// FIXME: Remove with lang team approval.let issue_145575_hack = Some(binding) == extern_prelude_flag_binding&& extern_prelude_item_binding.is_some()&& extern_prelude_item_binding != Some(innermost_binding);if let Some(kind) = ambiguity_error_kind&& !issue_145575_hack{let misc = |f: Flags| {if f.contains(Flags::MISC_SUGGEST_CRATE) {AmbiguityErrorMisc::SuggestCrate} else if f.contains(Flags::MISC_SUGGEST_SELF) {AmbiguityErrorMisc::SuggestSelf} else if f.contains(Flags::MISC_FROM_PRELUDE) {AmbiguityErrorMisc::FromPrelude} else {AmbiguityErrorMisc::None}};self.ambiguity_errors.push(AmbiguityError {kind,ident: orig_ident,b1: innermost_binding,b2: binding,warning: false,misc1: misc(innermost_flags),misc2: misc(flags),});return true;
if let Some(kind) = ambiguity_error_kind {// Skip ambiguity errors for extern flag bindings "overridden"// by extern item bindings.// FIXME: Remove with lang team approval.let issue_145575_hack = Some(binding) == extern_prelude_flag_binding&& extern_prelude_item_binding.is_some()&& extern_prelude_item_binding != Some(innermost_binding);if issue_145575_hack {self.issue_145575_hack_applied = true;} else {let misc = |f: Flags| {if f.contains(Flags::MISC_SUGGEST_CRATE) {AmbiguityErrorMisc::SuggestCrate} else if f.contains(Flags::MISC_SUGGEST_SELF) {AmbiguityErrorMisc::SuggestSelf} else if f.contains(Flags::MISC_FROM_PRELUDE) {AmbiguityErrorMisc::FromPrelude} else {AmbiguityErrorMisc::None}};self.ambiguity_errors.push(AmbiguityError {kind,ident: orig_ident,b1: innermost_binding,b2: binding,warning: false,misc1: misc(innermost_flags),misc2: misc(flags),});return true;} } false
diff --git i/compiler/rustc_resolve/src/imports.rs w/compiler/rustc_resolve/src/imports.rs index 4ef87af5605..4e0f3db5982 100644 --- i/compiler/rustc_resolve/src/imports.rs +++ w/compiler/rustc_resolve/src/imports.rs @@ -1170,7 +1170,7 @@ fn finalize_import(&mut self, import: Import<'ra>) -> Option<UnresolvedImportErr return; } if let Some(initial_res) = initial_res {
if res != initial_res {
if res != initial_res && !this.issue_145575_hack_applied { span_bug!(import.span, "inconsistent resolution for an import"); } } else if this.privacy_errors.is_empty() {
diff --git i/compiler/rustc_resolve/src/lib.rs w/compiler/rustc_resolve/src/lib.rs index 8132bf577d8..7e06b8511e3 100644 --- i/compiler/rustc_resolve/src/lib.rs +++ w/compiler/rustc_resolve/src/lib.rs @@ -1186,6 +1186,7 @@ pub struct Resolver<'ra, 'tcx> { privacy_errors: Vec<PrivacyError<'ra>> = Vec::new(), /// Ambiguity errors are delayed for deduplication. ambiguity_errors: Vec<AmbiguityError<'ra>> = Vec::new(),
- issue_145575_hack_applied: bool = false,
///
useinjections are delayed for better placement and deduplication. use_injections: Vec<UseError<'tcx>> = Vec::new(), /// Crate-local macro expandedmacro_exportreferred to by a module-relative path.