@@ -23,7 +23,7 @@ use rustc_errors::{
2323 MultiSpan , Style ,
2424} ;
2525use rustc_hir as hir;
26- use rustc_hir:: def:: Namespace ;
26+ use rustc_hir:: def:: { DefKind , Namespace , Res } ;
2727use rustc_hir:: def_id:: { DefId , LocalDefId } ;
2828use rustc_hir:: intravisit:: Visitor ;
2929use rustc_hir:: { GenericParam , Item , Node } ;
@@ -2367,12 +2367,12 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
23672367 && let [
23682368 ..,
23692369 trait_path_segment @ hir:: PathSegment {
2370- res : rustc_hir :: def :: Res :: Def ( rustc_hir :: def :: DefKind :: Trait , trait_id) ,
2370+ res : Res :: Def ( DefKind :: Trait , trait_id) ,
23712371 ..
23722372 } ,
23732373 hir:: PathSegment {
23742374 ident : assoc_item_name,
2375- res : rustc_hir :: def :: Res :: Def ( _, item_id) ,
2375+ res : Res :: Def ( _, item_id) ,
23762376 ..
23772377 }
23782378 ] = path. segments
@@ -2383,45 +2383,68 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
23832383 let ( verb, noun) = match self . tcx . associated_item ( item_id) . kind {
23842384 ty:: AssocKind :: Const => ( "refer to the" , "constant" ) ,
23852385 ty:: AssocKind :: Fn => ( "call" , "function" ) ,
2386- ty:: AssocKind :: Type => ( "refer to the" , "type" ) , // this is already covered by E0223, but this single match arm doesn't hurt here
2386+ // This is already covered by E0223, but this following single match
2387+ // arm doesn't hurt here.
2388+ ty:: AssocKind :: Type => ( "refer to the" , "type" ) ,
23872389 } ;
23882390
23892391 // Replace the more general E0283 with a more specific error
23902392 err. cancel ( ) ;
23912393 err = self . tcx . sess . struct_span_err_with_code (
23922394 span,
23932395 format ! (
2394- "cannot {verb} associated {noun} on trait without specifying the corresponding `impl` type" ,
2396+ "cannot {verb} associated {noun} on trait without specifying the \
2397+ corresponding `impl` type",
23952398 ) ,
23962399 rustc_errors:: error_code!( E0790 ) ,
23972400 ) ;
23982401
23992402 if let Some ( local_def_id) = data. trait_ref . def_id . as_local ( )
2400- && let Some ( hir:: Node :: Item ( hir:: Item { ident : trait_name, kind : hir:: ItemKind :: Trait ( _, _, _, _, trait_item_refs) , .. } ) ) = self . tcx . hir ( ) . find_by_def_id ( local_def_id)
2401- && let Some ( method_ref) = trait_item_refs. iter ( ) . find ( |item_ref| item_ref. ident == * assoc_item_name) {
2402- err. span_label ( method_ref. span , format ! ( "`{trait_name}::{assoc_item_name}` defined here" ) ) ;
2403+ && let Some ( hir:: Node :: Item ( hir:: Item {
2404+ ident : trait_name,
2405+ kind : hir:: ItemKind :: Trait ( _, _, _, _, trait_item_refs) ,
2406+ ..
2407+ } ) ) = self . tcx . hir ( ) . find_by_def_id ( local_def_id)
2408+ && let Some ( method_ref) = trait_item_refs
2409+ . iter ( )
2410+ . find ( |item_ref| item_ref. ident == * assoc_item_name)
2411+ {
2412+ err. span_label (
2413+ method_ref. span ,
2414+ format ! ( "`{trait_name}::{assoc_item_name}` defined here" ) ,
2415+ ) ;
24032416 }
24042417
24052418 err. span_label ( span, format ! ( "cannot {verb} associated {noun} of trait" ) ) ;
24062419
24072420 let trait_impls = self . tcx . trait_impls_of ( data. trait_ref . def_id ) ;
24082421
2409- if trait_impls . blanket_impls ( ) . is_empty ( )
2410- && let Some ( impl_def_id ) = trait_impls. non_blanket_impls ( ) . values ( ) . flatten ( ) . next ( )
2422+ if let Some ( impl_def_id ) =
2423+ trait_impls. non_blanket_impls ( ) . values ( ) . flatten ( ) . next ( )
24112424 {
2412- let non_blanket_impl_count = trait_impls. non_blanket_impls ( ) . values ( ) . flatten ( ) . count ( ) ;
2425+ let non_blanket_impl_count =
2426+ trait_impls. non_blanket_impls ( ) . values ( ) . flatten ( ) . count ( ) ;
24132427 // If there is only one implementation of the trait, suggest using it.
24142428 // Otherwise, use a placeholder comment for the implementation.
2415- let ( message, impl_suggestion) = if non_blanket_impl_count == 1 { (
2416- "use the fully-qualified path to the only available implementation" ,
2417- format ! ( "<{} as " , self . tcx. type_of( impl_def_id) . instantiate_identity( ) )
2418- ) } else {
2419- ( "use a fully-qualified path to a specific available implementation" ,
2420- "</* self type */ as " . to_string ( )
2421- ) } ;
2429+ let ( message, self_type) = if non_blanket_impl_count == 1 {
2430+ (
2431+ "use the fully-qualified path to the only available \
2432+ implementation",
2433+ format ! (
2434+ "{}" ,
2435+ self . tcx. type_of( impl_def_id) . instantiate_identity( )
2436+ ) ,
2437+ )
2438+ } else {
2439+ (
2440+ "use a fully-qualified path to a specific available \
2441+ implementation",
2442+ "/* self type */" . to_string ( ) ,
2443+ )
2444+ } ;
24222445 let mut suggestions = vec ! [ (
24232446 path. span. shrink_to_lo( ) ,
2424- impl_suggestion
2447+ format! ( "<{self_type} as " ) ,
24252448 ) ] ;
24262449 if let Some ( generic_arg) = trait_path_segment. args {
24272450 let between_span = trait_path_segment. ident . span . between ( generic_arg. span_ext ) ;
0 commit comments