From 2221d3a624cdd490c8420e6bcfecc48cd355655d Mon Sep 17 00:00:00 2001 From: Romain Perier Date: Sat, 15 Nov 2025 18:34:02 +0100 Subject: [PATCH] Untruthful multiple different versions of a crate in the dependency graph Currently, If `expected_def_id` and `another_trait_def_id` have their crate imported as ExternCrateSource::Path the method get_extern_crate_renamed_symbol() will return None for both, resulting in a false positive. This fixes the issue by using a slitly different approach, we use a predicate instead and do the comparison of the item names only when both crates are imported as ExternCrateSource::Extern, otherwise false is returned. --- .../src/error_reporting/traits/mod.rs | 36 ++++++++++++------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index befc83a592c0f..dc7ea3d14e9a3 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -22,7 +22,8 @@ use rustc_infer::traits::{ }; use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt as _}; -use rustc_span::{DesugaringKind, ErrorGuaranteed, ExpnKind, Span, Symbol}; +use rustc_session::cstore::{ExternCrate, ExternCrateSource}; +use rustc_span::{DesugaringKind, ErrorGuaranteed, ExpnKind, Span, sym}; use tracing::{info, instrument}; pub use self::overflow::*; @@ -353,14 +354,26 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } - fn get_extern_crate_renamed_symbol(&self, trait_def_id: DefId) -> Option { - if !trait_def_id.is_local() - && let Some(data) = self.tcx.extern_crate(trait_def_id.krate) - && let rustc_session::cstore::ExternCrateSource::Extern(def_id) = data.src - { - self.tcx.opt_item_name(def_id) - } else { - None + fn extern_crates_with_the_same_name( + &self, + expected_def_id: DefId, + trait_def_id: DefId, + ) -> bool { + if expected_def_id.is_local() || trait_def_id.is_local() { + return false; + } + match ( + self.tcx.extern_crate(expected_def_id.krate), + self.tcx.extern_crate(trait_def_id.krate), + ) { + ( + Some(ExternCrate { src: ExternCrateSource::Extern(expected_def_id), .. }), + Some(ExternCrate { src: ExternCrateSource::Extern(trait_def_id), .. }), + ) => { + let expected_sym = self.tcx.item_name(expected_def_id); + expected_sym == self.tcx.item_name(trait_def_id) && expected_sym != sym::std + } + _ => false, } } @@ -377,13 +390,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { { let krate = self.tcx.crate_name(expected_did.krate); let name = self.tcx.item_name(expected_did); - let locally_renamed_krate = self - .get_extern_crate_renamed_symbol(expected_did) - .map_or(None, |s| if s != krate { Some(s) } else { None }); let definitions_with_same_path: UnordSet<_> = found_dids .filter(|def_id| { def_id.krate != expected_did.krate - && (locally_renamed_krate == self.get_extern_crate_renamed_symbol(*def_id) + && (self.extern_crates_with_the_same_name(expected_did, *def_id) || self.tcx.crate_name(def_id.krate) == krate) && self.tcx.item_name(def_id) == name })