@@ -23,7 +23,7 @@ use rustc_errors::{
23
23
MultiSpan , Style ,
24
24
} ;
25
25
use rustc_hir as hir;
26
- use rustc_hir:: def:: Namespace ;
26
+ use rustc_hir:: def:: { DefKind , Namespace , Res } ;
27
27
use rustc_hir:: def_id:: { DefId , LocalDefId } ;
28
28
use rustc_hir:: intravisit:: Visitor ;
29
29
use rustc_hir:: { GenericParam , Item , Node } ;
@@ -2369,12 +2369,12 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
2369
2369
&& let [
2370
2370
..,
2371
2371
trait_path_segment @ hir:: PathSegment {
2372
- res : rustc_hir :: def :: Res :: Def ( rustc_hir :: def :: DefKind :: Trait , trait_id) ,
2372
+ res : Res :: Def ( DefKind :: Trait , trait_id) ,
2373
2373
..
2374
2374
} ,
2375
2375
hir:: PathSegment {
2376
2376
ident : assoc_item_name,
2377
- res : rustc_hir :: def :: Res :: Def ( _, item_id) ,
2377
+ res : Res :: Def ( _, item_id) ,
2378
2378
..
2379
2379
}
2380
2380
] = path. segments
@@ -2385,45 +2385,68 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
2385
2385
let ( verb, noun) = match self . tcx . associated_item ( item_id) . kind {
2386
2386
ty:: AssocKind :: Const => ( "refer to the" , "constant" ) ,
2387
2387
ty:: AssocKind :: Fn => ( "call" , "function" ) ,
2388
- ty:: AssocKind :: Type => ( "refer to the" , "type" ) , // this is already covered by E0223, but this single match arm doesn't hurt here
2388
+ // This is already covered by E0223, but this following single match
2389
+ // arm doesn't hurt here.
2390
+ ty:: AssocKind :: Type => ( "refer to the" , "type" ) ,
2389
2391
} ;
2390
2392
2391
2393
// Replace the more general E0283 with a more specific error
2392
2394
err. cancel ( ) ;
2393
2395
err = self . tcx . sess . struct_span_err_with_code (
2394
2396
span,
2395
2397
format ! (
2396
- "cannot {verb} associated {noun} on trait without specifying the corresponding `impl` type" ,
2398
+ "cannot {verb} associated {noun} on trait without specifying the \
2399
+ corresponding `impl` type",
2397
2400
) ,
2398
2401
rustc_errors:: error_code!( E0790 ) ,
2399
2402
) ;
2400
2403
2401
2404
if let Some ( local_def_id) = data. trait_ref . def_id . as_local ( )
2402
- && 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)
2403
- && let Some ( method_ref) = trait_item_refs. iter ( ) . find ( |item_ref| item_ref. ident == * assoc_item_name) {
2404
- err. span_label ( method_ref. span , format ! ( "`{trait_name}::{assoc_item_name}` defined here" ) ) ;
2405
+ && let Some ( hir:: Node :: Item ( hir:: Item {
2406
+ ident : trait_name,
2407
+ kind : hir:: ItemKind :: Trait ( _, _, _, _, trait_item_refs) ,
2408
+ ..
2409
+ } ) ) = self . tcx . hir ( ) . find_by_def_id ( local_def_id)
2410
+ && let Some ( method_ref) = trait_item_refs
2411
+ . iter ( )
2412
+ . find ( |item_ref| item_ref. ident == * assoc_item_name)
2413
+ {
2414
+ err. span_label (
2415
+ method_ref. span ,
2416
+ format ! ( "`{trait_name}::{assoc_item_name}` defined here" ) ,
2417
+ ) ;
2405
2418
}
2406
2419
2407
2420
err. span_label ( span, format ! ( "cannot {verb} associated {noun} of trait" ) ) ;
2408
2421
2409
2422
let trait_impls = self . tcx . trait_impls_of ( data. trait_ref . def_id ) ;
2410
2423
2411
- if trait_impls . blanket_impls ( ) . is_empty ( )
2412
- && let Some ( impl_def_id ) = trait_impls. non_blanket_impls ( ) . values ( ) . flatten ( ) . next ( )
2424
+ if let Some ( impl_def_id ) =
2425
+ trait_impls. non_blanket_impls ( ) . values ( ) . flatten ( ) . next ( )
2413
2426
{
2414
- let non_blanket_impl_count = trait_impls. non_blanket_impls ( ) . values ( ) . flatten ( ) . count ( ) ;
2427
+ let non_blanket_impl_count =
2428
+ trait_impls. non_blanket_impls ( ) . values ( ) . flatten ( ) . count ( ) ;
2415
2429
// If there is only one implementation of the trait, suggest using it.
2416
2430
// Otherwise, use a placeholder comment for the implementation.
2417
- let ( message, impl_suggestion) = if non_blanket_impl_count == 1 { (
2418
- "use the fully-qualified path to the only available implementation" ,
2419
- format ! ( "<{} as " , self . tcx. type_of( impl_def_id) . instantiate_identity( ) )
2420
- ) } else {
2421
- ( "use a fully-qualified path to a specific available implementation" ,
2422
- "</* self type */ as " . to_string ( )
2423
- ) } ;
2431
+ let ( message, self_type) = if non_blanket_impl_count == 1 {
2432
+ (
2433
+ "use the fully-qualified path to the only available \
2434
+ implementation",
2435
+ format ! (
2436
+ "{}" ,
2437
+ self . tcx. type_of( impl_def_id) . instantiate_identity( )
2438
+ ) ,
2439
+ )
2440
+ } else {
2441
+ (
2442
+ "use a fully-qualified path to a specific available \
2443
+ implementation",
2444
+ "/* self type */" . to_string ( ) ,
2445
+ )
2446
+ } ;
2424
2447
let mut suggestions = vec ! [ (
2425
2448
path. span. shrink_to_lo( ) ,
2426
- impl_suggestion
2449
+ format! ( "<{self_type} as " ) ,
2427
2450
) ] ;
2428
2451
if let Some ( generic_arg) = trait_path_segment. args {
2429
2452
let between_span = trait_path_segment. ident . span . between ( generic_arg. span_ext ) ;
0 commit comments