@@ -25,7 +25,7 @@ use rustc_errors::{
25
25
MultiSpan , Style ,
26
26
} ;
27
27
use rustc_hir as hir;
28
- use rustc_hir:: def:: Namespace ;
28
+ use rustc_hir:: def:: { DefKind , Namespace , Res } ;
29
29
use rustc_hir:: def_id:: { DefId , LocalDefId } ;
30
30
use rustc_hir:: intravisit:: Visitor ;
31
31
use rustc_hir:: { GenericParam , Item , Node } ;
@@ -2453,12 +2453,12 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
2453
2453
&& let [
2454
2454
..,
2455
2455
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) ,
2457
2457
..
2458
2458
} ,
2459
2459
hir:: PathSegment {
2460
2460
ident : assoc_item_name,
2461
- res : rustc_hir :: def :: Res :: Def ( _, item_id) ,
2461
+ res : Res :: Def ( _, item_id) ,
2462
2462
..
2463
2463
}
2464
2464
] = path. segments
@@ -2469,45 +2469,68 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
2469
2469
let ( verb, noun) = match self . tcx . associated_item ( item_id) . kind {
2470
2470
ty:: AssocKind :: Const => ( "refer to the" , "constant" ) ,
2471
2471
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" ) ,
2473
2475
} ;
2474
2476
2475
2477
// Replace the more general E0283 with a more specific error
2476
2478
err. cancel ( ) ;
2477
2479
err = self . tcx . sess . struct_span_err_with_code (
2478
2480
span,
2479
2481
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",
2481
2484
) ,
2482
2485
rustc_errors:: error_code!( E0790 ) ,
2483
2486
) ;
2484
2487
2485
2488
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
+ ) ;
2489
2502
}
2490
2503
2491
2504
err. span_label ( span, format ! ( "cannot {verb} associated {noun} of trait" ) ) ;
2492
2505
2493
2506
let trait_impls = self . tcx . trait_impls_of ( data. trait_ref . def_id ) ;
2494
2507
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 ( )
2497
2510
{
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 ( ) ;
2499
2513
// If there is only one implementation of the trait, suggest using it.
2500
2514
// 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
+ } ;
2508
2531
let mut suggestions = vec ! [ (
2509
2532
path. span. shrink_to_lo( ) ,
2510
- impl_suggestion
2533
+ format! ( "<{self_type} as " ) ,
2511
2534
) ] ;
2512
2535
if let Some ( generic_arg) = trait_path_segment. args {
2513
2536
let between_span = trait_path_segment. ident . span . between ( generic_arg. span_ext ) ;
0 commit comments