Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 23 additions & 13 deletions compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down Expand Up @@ -353,14 +354,26 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
}
}

fn get_extern_crate_renamed_symbol(&self, trait_def_id: DefId) -> Option<Symbol> {
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the check for != std?

Copy link
Contributor Author

@rperier rperier Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's weird, it seems that, in some cases, there are tests in ui suite that report two crates being imported as std. In such a case, the predicate returns true. It's the test tests/ui/typeck/issue-50687-ice-on-borrow.rs, if I remember correctly. Note: I had the same kind of reports with the old version.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that seems worth debugging because right now it feels arbitrary.

In such cases we should figure out why things work the way they do as

  • it prevents confusing future readers by adding a comment#
  • the "arbitrary" check may actually hide a more general underlying issue and without properly fixing it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, no my bad, it's the tests tests/ui/suggestions/issue-105645.rs and tests/ui/suggestions/mut-borrow-needed-by-trait.rs both report : "there are multiple different versions of crate std in the dependency graph" :=D .

Yeah, I agree, I am going to investigate.

}
_ => false,
}
}

Expand All @@ -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
})
Expand Down
Loading