@@ -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
@@ -249,6 +249,8 @@ fn suggest_restriction(
249
249
sugg. extend ( ty_spans. into_iter ( ) . map ( |s| ( s, type_param_name. to_string ( ) ) ) ) ;
250
250
251
251
// Suggest `fn foo<T: Trait>(t: T) where <T as Trait>::A: Bound`.
252
+ // FIXME: once `#![feature(associated_type_bounds)]` is stabilized, we should suggest
253
+ // `fn foo(t: impl Trait<A: Bound>)` instead.
252
254
err. multipart_suggestion (
253
255
"introduce a type parameter with a trait bound instead of using `impl Trait`" ,
254
256
sugg,
@@ -1702,3 +1704,29 @@ impl<'v> Visitor<'v> for ReturnsVisitor<'v> {
1702
1704
hir:: intravisit:: walk_body ( self , body) ;
1703
1705
}
1704
1706
}
1707
+
1708
+ pub trait NextTypeParamName {
1709
+ fn next_type_param_name ( & self , name : Option < & str > ) -> String ;
1710
+ }
1711
+
1712
+ impl NextTypeParamName for & [ hir:: GenericParam < ' _ > ] {
1713
+ fn next_type_param_name ( & self , name : Option < & str > ) -> String {
1714
+ // This is the whitelist of possible parameter names that we might suggest.
1715
+ let name = name. and_then ( |n| n. chars ( ) . next ( ) ) . map ( |c| c. to_string ( ) . to_uppercase ( ) ) ;
1716
+ let name = name. as_ref ( ) . map ( |s| s. as_str ( ) ) ;
1717
+ let possible_names = [ name. unwrap_or ( "T" ) , "T" , "U" , "V" , "X" , "Y" , "Z" , "A" , "B" , "C" ] ;
1718
+ let used_names = self
1719
+ . iter ( )
1720
+ . filter_map ( |p| match p. name {
1721
+ hir:: ParamName :: Plain ( ident) => Some ( ident. name ) ,
1722
+ _ => None ,
1723
+ } )
1724
+ . collect :: < Vec < _ > > ( ) ;
1725
+
1726
+ possible_names
1727
+ . iter ( )
1728
+ . find ( |n| !used_names. contains ( & Symbol :: intern ( n) ) )
1729
+ . unwrap_or ( & "ParamName" )
1730
+ . to_string ( )
1731
+ }
1732
+ }
0 commit comments