@@ -12,7 +12,7 @@ use std::{fmt, iter};
1212use rustc_data_structures:: fx:: { FxIndexMap , FxIndexSet } ;
1313use rustc_data_structures:: unord:: UnordSet ;
1414use rustc_errors:: { Applicability , Diag , E0038 , E0276 , MultiSpan , struct_span_code_err} ;
15- use rustc_hir:: def_id:: { DefId , LocalDefId } ;
15+ use rustc_hir:: def_id:: { DefId , LOCAL_CRATE , LocalDefId } ;
1616use rustc_hir:: intravisit:: Visitor ;
1717use rustc_hir:: { self as hir, AmbigArg } ;
1818use rustc_infer:: traits:: solve:: Goal ;
@@ -22,7 +22,8 @@ use rustc_infer::traits::{
2222} ;
2323use rustc_middle:: ty:: print:: { PrintTraitRefExt as _, with_no_trimmed_paths} ;
2424use rustc_middle:: ty:: { self , Ty , TyCtxt , TypeVisitableExt as _} ;
25- use rustc_span:: { DesugaringKind , ErrorGuaranteed , ExpnKind , Span , Symbol } ;
25+ use rustc_session:: cstore:: { ExternCrate , ExternCrateSource } ;
26+ use rustc_span:: { DesugaringKind , ErrorGuaranteed , ExpnKind , Span } ;
2627use tracing:: { info, instrument} ;
2728
2829pub use self :: overflow:: * ;
@@ -353,14 +354,37 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
353354 }
354355 }
355356
356- fn get_extern_crate_renamed_symbol ( & self , trait_def_id : DefId ) -> Option < Symbol > {
357- if !trait_def_id. is_local ( )
358- && let Some ( data) = self . tcx . extern_crate ( trait_def_id. krate )
359- && let rustc_session:: cstore:: ExternCrateSource :: Extern ( def_id) = data. src
360- {
361- self . tcx . opt_item_name ( def_id)
362- } else {
363- None
357+ /// If the crates of `expected_def_id` and `trait_def_id` are imported as extern crate
358+ /// under the same name (`extern crate foo as a` and `extern crate bar as a`) returns true,
359+ /// otherwise returns false.
360+ fn extern_crates_with_the_same_name (
361+ & self ,
362+ expected_def_id : DefId ,
363+ trait_def_id : DefId ,
364+ ) -> bool {
365+ if expected_def_id. is_local ( ) || trait_def_id. is_local ( ) {
366+ return false ;
367+ }
368+ // We only compare direct dependencies of the current crate, so it avoids unnecessary
369+ // processing and excludes indirect dependencies, like `std` or `core`. In such a case
370+ // both would be imported under the same name `std`.
371+ match (
372+ self . tcx . extern_crate ( expected_def_id. krate ) ,
373+ self . tcx . extern_crate ( trait_def_id. krate ) ,
374+ ) {
375+ (
376+ Some ( ExternCrate {
377+ src : ExternCrateSource :: Extern ( expected_def_id) ,
378+ dependency_of : LOCAL_CRATE ,
379+ ..
380+ } ) ,
381+ Some ( ExternCrate {
382+ src : ExternCrateSource :: Extern ( trait_def_id) ,
383+ dependency_of : LOCAL_CRATE ,
384+ ..
385+ } ) ,
386+ ) => self . tcx . item_name ( expected_def_id) == self . tcx . item_name ( trait_def_id) ,
387+ _ => false ,
364388 }
365389 }
366390
@@ -377,13 +401,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
377401 {
378402 let krate = self . tcx . crate_name ( expected_did. krate ) ;
379403 let name = self . tcx . item_name ( expected_did) ;
380- let locally_renamed_krate = self
381- . get_extern_crate_renamed_symbol ( expected_did)
382- . map_or ( None , |s| if s != krate { Some ( s) } else { None } ) ;
383404 let definitions_with_same_path: UnordSet < _ > = found_dids
384405 . filter ( |def_id| {
385406 def_id. krate != expected_did. krate
386- && ( locally_renamed_krate == self . get_extern_crate_renamed_symbol ( * def_id)
407+ && ( self . extern_crates_with_the_same_name ( expected_did , * def_id)
387408 || self . tcx . crate_name ( def_id. krate ) == krate)
388409 && self . tcx . item_name ( def_id) == name
389410 } )
0 commit comments