@@ -25,7 +25,7 @@ use rustc_errors::{
2525 MultiSpan , Style ,
2626} ;
2727use rustc_hir as hir;
28- use rustc_hir:: def:: Namespace ;
28+ use rustc_hir:: def:: { DefKind , Namespace , Res } ;
2929use rustc_hir:: def_id:: { DefId , LocalDefId } ;
3030use rustc_hir:: intravisit:: Visitor ;
3131use rustc_hir:: { GenericParam , Item , Node } ;
@@ -2453,12 +2453,12 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
24532453 && let [
24542454 ..,
24552455 trait_path_segment @ hir:: PathSegment {
2456- res : rustc_hir :: def :: Res :: Def ( rustc_hir :: def :: DefKind :: Trait , trait_id) ,
2456+ res : Res :: Def ( DefKind :: Trait , trait_id) ,
24572457 ..
24582458 } ,
24592459 hir:: PathSegment {
24602460 ident : assoc_item_name,
2461- res : rustc_hir :: def :: Res :: Def ( _, item_id) ,
2461+ res : Res :: Def ( _, item_id) ,
24622462 ..
24632463 }
24642464 ] = path. segments
@@ -2469,45 +2469,68 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
24692469 let ( verb, noun) = match self . tcx . associated_item ( item_id) . kind {
24702470 ty:: AssocKind :: Const => ( "refer to the" , "constant" ) ,
24712471 ty:: AssocKind :: Fn => ( "call" , "function" ) ,
2472- ty:: AssocKind :: Type => ( "refer to the" , "type" ) , // this is already covered by E0223, but this single match arm doesn't hurt here
2472+ // This is already covered by E0223, but this following single match
2473+ // arm doesn't hurt here.
2474+ ty:: AssocKind :: Type => ( "refer to the" , "type" ) ,
24732475 } ;
24742476
24752477 // Replace the more general E0283 with a more specific error
24762478 err. cancel ( ) ;
24772479 err = self . tcx . sess . struct_span_err_with_code (
24782480 span,
24792481 format ! (
2480- "cannot {verb} associated {noun} on trait without specifying the corresponding `impl` type" ,
2482+ "cannot {verb} associated {noun} on trait without specifying the \
2483+ corresponding `impl` type",
24812484 ) ,
24822485 rustc_errors:: error_code!( E0790 ) ,
24832486 ) ;
24842487
24852488 if let Some ( local_def_id) = data. trait_ref . def_id . as_local ( )
2486- && 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)
2487- && let Some ( method_ref) = trait_item_refs. iter ( ) . find ( |item_ref| item_ref. ident == * assoc_item_name) {
2488- err. span_label ( method_ref. span , format ! ( "`{trait_name}::{assoc_item_name}` defined here" ) ) ;
2489+ && let Some ( hir:: Node :: Item ( hir:: Item {
2490+ ident : trait_name,
2491+ kind : hir:: ItemKind :: Trait ( _, _, _, _, trait_item_refs) ,
2492+ ..
2493+ } ) ) = self . tcx . hir ( ) . find_by_def_id ( local_def_id)
2494+ && let Some ( method_ref) = trait_item_refs
2495+ . iter ( )
2496+ . find ( |item_ref| item_ref. ident == * assoc_item_name)
2497+ {
2498+ err. span_label (
2499+ method_ref. span ,
2500+ format ! ( "`{trait_name}::{assoc_item_name}` defined here" ) ,
2501+ ) ;
24892502 }
24902503
24912504 err. span_label ( span, format ! ( "cannot {verb} associated {noun} of trait" ) ) ;
24922505
24932506 let trait_impls = self . tcx . trait_impls_of ( data. trait_ref . def_id ) ;
24942507
2495- if trait_impls . blanket_impls ( ) . is_empty ( )
2496- && let Some ( impl_def_id ) = trait_impls. non_blanket_impls ( ) . values ( ) . flatten ( ) . next ( )
2508+ if let Some ( impl_def_id ) =
2509+ trait_impls. non_blanket_impls ( ) . values ( ) . flatten ( ) . next ( )
24972510 {
2498- let non_blanket_impl_count = trait_impls. non_blanket_impls ( ) . values ( ) . flatten ( ) . count ( ) ;
2511+ let non_blanket_impl_count =
2512+ trait_impls. non_blanket_impls ( ) . values ( ) . flatten ( ) . count ( ) ;
24992513 // If there is only one implementation of the trait, suggest using it.
25002514 // Otherwise, use a placeholder comment for the implementation.
2501- let ( message, impl_suggestion) = if non_blanket_impl_count == 1 { (
2502- "use the fully-qualified path to the only available implementation" ,
2503- format ! ( "<{} as " , self . tcx. type_of( impl_def_id) . instantiate_identity( ) )
2504- ) } else {
2505- ( "use a fully-qualified path to a specific available implementation" ,
2506- "</* self type */ as " . to_string ( )
2507- ) } ;
2515+ let ( message, self_type) = if non_blanket_impl_count == 1 {
2516+ (
2517+ "use the fully-qualified path to the only available \
2518+ implementation",
2519+ format ! (
2520+ "{}" ,
2521+ self . tcx. type_of( impl_def_id) . instantiate_identity( )
2522+ ) ,
2523+ )
2524+ } else {
2525+ (
2526+ "use a fully-qualified path to a specific available \
2527+ implementation",
2528+ "/* self type */" . to_string ( ) ,
2529+ )
2530+ } ;
25082531 let mut suggestions = vec ! [ (
25092532 path. span. shrink_to_lo( ) ,
2510- impl_suggestion
2533+ format! ( "<{self_type} as " ) ,
25112534 ) ] ;
25122535 if let Some ( generic_arg) = trait_path_segment. args {
25132536 let between_span = trait_path_segment. ident . span . between ( generic_arg. span_ext ) ;
0 commit comments