1
+ use either:: Either ;
1
2
use syntax:: {
2
3
ast:: {
3
4
self , AstNode , HasName , HasTypeBounds ,
@@ -30,10 +31,11 @@ pub(crate) fn move_bounds_to_where_clause(
30
31
) -> Option < ( ) > {
31
32
let type_param_list = ctx. find_node_at_offset :: < ast:: GenericParamList > ( ) ?;
32
33
33
- let mut type_params = type_param_list. type_or_const_params ( ) ;
34
+ let mut type_params = type_param_list. generic_params ( ) ;
34
35
if type_params. all ( |p| match p {
35
- ast:: TypeOrConstParam :: Type ( t) => t. type_bound_list ( ) . is_none ( ) ,
36
- ast:: TypeOrConstParam :: Const ( _) => true ,
36
+ ast:: GenericParam :: TypeParam ( t) => t. type_bound_list ( ) . is_none ( ) ,
37
+ ast:: GenericParam :: LifetimeParam ( l) => l. type_bound_list ( ) . is_none ( ) ,
38
+ ast:: GenericParam :: ConstParam ( _) => true ,
37
39
} ) {
38
40
return None ;
39
41
}
@@ -53,20 +55,23 @@ pub(crate) fn move_bounds_to_where_clause(
53
55
match parent {
54
56
ast:: Fn ( it) => it. get_or_create_where_clause( ) ,
55
57
ast:: Trait ( it) => it. get_or_create_where_clause( ) ,
58
+ ast:: TraitAlias ( it) => it. get_or_create_where_clause( ) ,
56
59
ast:: Impl ( it) => it. get_or_create_where_clause( ) ,
57
60
ast:: Enum ( it) => it. get_or_create_where_clause( ) ,
58
61
ast:: Struct ( it) => it. get_or_create_where_clause( ) ,
62
+ ast:: TypeAlias ( it) => it. get_or_create_where_clause( ) ,
59
63
_ => return ,
60
64
}
61
65
} ;
62
66
63
- for toc_param in type_param_list. type_or_const_params ( ) {
64
- let type_param = match toc_param {
65
- ast:: TypeOrConstParam :: Type ( x) => x,
66
- ast:: TypeOrConstParam :: Const ( _) => continue ,
67
+ for generic_param in type_param_list. generic_params ( ) {
68
+ let param: & dyn HasTypeBounds = match & generic_param {
69
+ ast:: GenericParam :: TypeParam ( t) => t,
70
+ ast:: GenericParam :: LifetimeParam ( l) => l,
71
+ ast:: GenericParam :: ConstParam ( _) => continue ,
67
72
} ;
68
- if let Some ( tbl) = type_param . type_bound_list ( ) {
69
- if let Some ( predicate) = build_predicate ( type_param ) {
73
+ if let Some ( tbl) = param . type_bound_list ( ) {
74
+ if let Some ( predicate) = build_predicate ( generic_param ) {
70
75
where_clause. add_predicate ( predicate)
71
76
}
72
77
tbl. remove ( )
@@ -76,9 +81,23 @@ pub(crate) fn move_bounds_to_where_clause(
76
81
)
77
82
}
78
83
79
- fn build_predicate ( param : ast:: TypeParam ) -> Option < ast:: WherePred > {
80
- let path = make:: ext:: ident_path ( & param. name ( ) ?. syntax ( ) . to_string ( ) ) ;
81
- let predicate = make:: where_pred ( make:: ty_path ( path) , param. type_bound_list ( ) ?. bounds ( ) ) ;
84
+ fn build_predicate ( param : ast:: GenericParam ) -> Option < ast:: WherePred > {
85
+ let target = match & param {
86
+ ast:: GenericParam :: TypeParam ( t) => {
87
+ Either :: Right ( make:: ty_path ( make:: ext:: ident_path ( & t. name ( ) ?. to_string ( ) ) ) )
88
+ }
89
+ ast:: GenericParam :: LifetimeParam ( l) => Either :: Left ( l. lifetime ( ) ?) ,
90
+ ast:: GenericParam :: ConstParam ( _) => return None ,
91
+ } ;
92
+ let predicate = make:: where_pred (
93
+ target,
94
+ match param {
95
+ ast:: GenericParam :: TypeParam ( t) => t. type_bound_list ( ) ?,
96
+ ast:: GenericParam :: LifetimeParam ( l) => l. type_bound_list ( ) ?,
97
+ ast:: GenericParam :: ConstParam ( _) => return None ,
98
+ }
99
+ . bounds ( ) ,
100
+ ) ;
82
101
Some ( predicate. clone_for_update ( ) )
83
102
}
84
103
@@ -123,4 +142,13 @@ mod tests {
123
142
r#"struct Pair<T>(T, T) where T: u32;"# ,
124
143
) ;
125
144
}
145
+
146
+ #[ test]
147
+ fn move_bounds_to_where_clause_trait ( ) {
148
+ check_assist (
149
+ move_bounds_to_where_clause,
150
+ r#"trait T<'a: 'static, $0T: u32> {}"# ,
151
+ r#"trait T<'a, T> where 'a: 'static, T: u32 {}"# ,
152
+ ) ;
153
+ }
126
154
}
0 commit comments