@@ -10,12 +10,12 @@ use rustc_hir as hir;
10
10
use rustc_hir:: def:: DefKind ;
11
11
use rustc_hir:: def_id:: DefId ;
12
12
use rustc_hir:: intravisit:: Visitor ;
13
- use rustc_hir:: { NextTypeParamName , Node } ;
13
+ use rustc_hir:: Node ;
14
14
use rustc_middle:: ty:: TypeckTables ;
15
15
use rustc_middle:: ty:: {
16
16
self , AdtKind , DefIdTree , ToPredicate , Ty , TyCtxt , TypeFoldable , WithConstness ,
17
17
} ;
18
- use rustc_span:: symbol:: { kw, sym} ;
18
+ use rustc_span:: symbol:: { kw, sym, Symbol } ;
19
19
use rustc_span:: { MultiSpan , Span , DUMMY_SP } ;
20
20
use std:: fmt;
21
21
@@ -248,6 +248,8 @@ fn suggest_restriction(
248
248
sugg. extend ( ty_spans. into_iter ( ) . map ( |s| ( s, type_param_name. to_string ( ) ) ) ) ;
249
249
250
250
// Suggest `fn foo<T: Trait>(t: T) where <T as Trait>::A: Bound`.
251
+ // FIXME: once `#![feature(associated_type_bounds)]` is stabilized, we should suggest
252
+ // `fn foo(t: impl Trait<A: Bound>)` instead.
251
253
err. multipart_suggestion (
252
254
"introduce a type parameter with a trait bound instead of using `impl Trait`" ,
253
255
sugg,
@@ -1694,3 +1696,29 @@ impl<'v> Visitor<'v> for ReturnsVisitor<'v> {
1694
1696
hir:: intravisit:: walk_body ( self , body) ;
1695
1697
}
1696
1698
}
1699
+
1700
+ pub trait NextTypeParamName {
1701
+ fn next_type_param_name ( & self , name : Option < & str > ) -> String ;
1702
+ }
1703
+
1704
+ impl NextTypeParamName for & [ hir:: GenericParam < ' _ > ] {
1705
+ fn next_type_param_name ( & self , name : Option < & str > ) -> String {
1706
+ // This is the whitelist of possible parameter names that we might suggest.
1707
+ let name = name. and_then ( |n| n. chars ( ) . next ( ) ) . map ( |c| c. to_string ( ) . to_uppercase ( ) ) ;
1708
+ let name = name. as_ref ( ) . map ( |s| s. as_str ( ) ) ;
1709
+ let possible_names = [ name. unwrap_or ( "T" ) , "T" , "U" , "V" , "X" , "Y" , "Z" , "A" , "B" , "C" ] ;
1710
+ let used_names = self
1711
+ . iter ( )
1712
+ . filter_map ( |p| match p. name {
1713
+ hir:: ParamName :: Plain ( ident) => Some ( ident. name ) ,
1714
+ _ => None ,
1715
+ } )
1716
+ . collect :: < Vec < _ > > ( ) ;
1717
+
1718
+ possible_names
1719
+ . iter ( )
1720
+ . find ( |n| !used_names. contains ( & Symbol :: intern ( n) ) )
1721
+ . unwrap_or ( & "ParamName" )
1722
+ . to_string ( )
1723
+ }
1724
+ }
0 commit comments