@@ -3498,8 +3498,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
34983498 . detect_and_explain_multiple_crate_versions (
34993499 err,
35003500 pick. item . def_id ,
3501- pick. item . ident ( self . tcx ) . span ,
3502- rcvr. hir_id . owner ,
3501+ rcvr. hir_id ,
35033502 * rcvr_ty,
35043503 ) ;
35053504 if pick. autoderefs == 0 && !trait_in_other_version_found {
@@ -3706,8 +3705,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
37063705 trait_in_other_version_found = self . detect_and_explain_multiple_crate_versions (
37073706 err,
37083707 assoc. def_id ,
3709- self . tcx . def_span ( assoc. def_id ) ,
3710- ty. hir_id . owner ,
3708+ ty. hir_id ,
37113709 rcvr_ty,
37123710 ) ;
37133711 }
@@ -4082,55 +4080,55 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
40824080 & self ,
40834081 err : & mut Diag < ' _ > ,
40844082 item_def_id : DefId ,
4085- item_span : Span ,
4086- owner : hir:: OwnerId ,
4083+ hir_id : hir:: HirId ,
40874084 rcvr_ty : Ty < ' _ > ,
40884085 ) -> bool {
4089- let pick_name = self . tcx . crate_name ( item_def_id. krate ) ;
4090- let trait_did = self . tcx . parent ( item_def_id) ;
4091- let trait_name = self . tcx . item_name ( trait_did) ;
4092- if let Some ( map) = self . tcx . in_scope_traits_map ( owner) {
4093- for trait_candidate in map. to_sorted_stable_ord ( ) . into_iter ( ) . flat_map ( |v| v. 1 . iter ( ) ) {
4094- let crate_name = self . tcx . crate_name ( trait_candidate. def_id . krate ) ;
4095- if trait_candidate. def_id . krate != item_def_id. krate && crate_name == pick_name {
4096- let msg = format ! (
4097- "there are multiple different versions of crate `{crate_name}` in the \
4098- dependency graph",
4099- ) ;
4100- let candidate_name = self . tcx . item_name ( trait_candidate. def_id ) ;
4101- if candidate_name == trait_name
4102- && let Some ( def_id) = trait_candidate. import_ids . get ( 0 )
4103- {
4104- let span = self . tcx . def_span ( * def_id) ;
4105- let mut multi_span: MultiSpan = span. into ( ) ;
4106- multi_span. push_span_label (
4107- span,
4108- format ! (
4109- "`{crate_name}` imported here doesn't correspond to the right \
4110- crate version",
4111- ) ,
4112- ) ;
4113- multi_span. push_span_label (
4114- self . tcx . def_span ( trait_candidate. def_id ) ,
4115- format ! ( "this is the trait that was imported" ) ,
4116- ) ;
4117- multi_span. push_span_label (
4118- self . tcx . def_span ( trait_did) ,
4119- format ! ( "this is the trait that is needed" ) ,
4120- ) ;
4121- multi_span. push_span_label (
4122- item_span,
4123- format ! ( "the method is available for `{rcvr_ty}` here" ) ,
4124- ) ;
4125- err. span_note ( multi_span, msg) ;
4126- } else {
4127- err. note ( msg) ;
4128- }
4129- return true ;
4130- }
4086+ let hir_id = self . tcx . parent_hir_id ( hir_id) ;
4087+ let Some ( traits) = self . tcx . in_scope_traits ( hir_id) else { return false } ;
4088+ if traits. is_empty ( ) {
4089+ return false ;
4090+ }
4091+ let trait_def_id = self . tcx . parent ( item_def_id) ;
4092+ let krate = self . tcx . crate_name ( trait_def_id. krate ) ;
4093+ let name = self . tcx . item_name ( trait_def_id) ;
4094+ let candidates: Vec < _ > = traits
4095+ . iter ( )
4096+ . filter ( |c| {
4097+ c. def_id . krate != trait_def_id. krate
4098+ && self . tcx . crate_name ( c. def_id . krate ) == krate
4099+ && self . tcx . item_name ( c. def_id ) == name
4100+ } )
4101+ . map ( |c| ( c. def_id , c. import_ids . get ( 0 ) . cloned ( ) ) )
4102+ . collect ( ) ;
4103+ if candidates. is_empty ( ) {
4104+ return false ;
4105+ }
4106+ let item_span = self . tcx . def_span ( item_def_id) ;
4107+ let msg = format ! (
4108+ "there are multiple different versions of crate `{krate}` in the dependency graph" ,
4109+ ) ;
4110+ let trait_span = self . tcx . def_span ( trait_def_id) ;
4111+ let mut multi_span: MultiSpan = trait_span. into ( ) ;
4112+ multi_span. push_span_label ( trait_span, format ! ( "this is the trait that is needed" ) ) ;
4113+ multi_span
4114+ . push_span_label ( item_span, format ! ( "the method is available for `{rcvr_ty}` here" ) ) ;
4115+ for ( def_id, import_def_id) in candidates {
4116+ if let Some ( import_def_id) = import_def_id {
4117+ multi_span. push_span_label (
4118+ self . tcx . def_span ( import_def_id) ,
4119+ format ! (
4120+ "`{name}` imported here doesn't correspond to the right version of crate \
4121+ `{krate}`",
4122+ ) ,
4123+ ) ;
41314124 }
4125+ multi_span. push_span_label (
4126+ self . tcx . def_span ( def_id) ,
4127+ format ! ( "this is the trait that was imported" ) ,
4128+ ) ;
41324129 }
4133- false
4130+ err. span_note ( multi_span, msg) ;
4131+ true
41344132 }
41354133
41364134 /// issue #102320, for `unwrap_or` with closure as argument, suggest `unwrap_or_else`
0 commit comments