@@ -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 } ;
@@ -2367,12 +2367,12 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
2367
2367
&& let [
2368
2368
..,
2369
2369
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) ,
2371
2371
..
2372
2372
} ,
2373
2373
hir:: PathSegment {
2374
2374
ident : assoc_item_name,
2375
- res : rustc_hir :: def :: Res :: Def ( _, item_id) ,
2375
+ res : Res :: Def ( _, item_id) ,
2376
2376
..
2377
2377
}
2378
2378
] = path. segments
@@ -2383,45 +2383,68 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
2383
2383
let ( verb, noun) = match self . tcx . associated_item ( item_id) . kind {
2384
2384
ty:: AssocKind :: Const => ( "refer to the" , "constant" ) ,
2385
2385
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" ) ,
2387
2389
} ;
2388
2390
2389
2391
// Replace the more general E0283 with a more specific error
2390
2392
err. cancel ( ) ;
2391
2393
err = self . tcx . sess . struct_span_err_with_code (
2392
2394
span,
2393
2395
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",
2395
2398
) ,
2396
2399
rustc_errors:: error_code!( E0790 ) ,
2397
2400
) ;
2398
2401
2399
2402
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
+ ) ;
2403
2416
}
2404
2417
2405
2418
err. span_label ( span, format ! ( "cannot {verb} associated {noun} of trait" ) ) ;
2406
2419
2407
2420
let trait_impls = self . tcx . trait_impls_of ( data. trait_ref . def_id ) ;
2408
2421
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 ( )
2411
2424
{
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 ( ) ;
2413
2427
// If there is only one implementation of the trait, suggest using it.
2414
2428
// 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
+ } ;
2422
2445
let mut suggestions = vec ! [ (
2423
2446
path. span. shrink_to_lo( ) ,
2424
- impl_suggestion
2447
+ format! ( "<{self_type} as " ) ,
2425
2448
) ] ;
2426
2449
if let Some ( generic_arg) = trait_path_segment. args {
2427
2450
let between_span = trait_path_segment. ident . span . between ( generic_arg. span_ext ) ;
0 commit comments