@@ -11,7 +11,9 @@ use syntax::{
11
11
12
12
#[ derive( Default ) ]
13
13
struct AstSubsts {
14
- types : Vec < ast:: TypeArg > ,
14
+ // ast::TypeArgs stands in fact for both type and const params
15
+ // as consts declared elsewhere look just like type params.
16
+ types_and_consts : Vec < ast:: TypeArg > ,
15
17
lifetimes : Vec < ast:: LifetimeArg > ,
16
18
}
17
19
@@ -108,7 +110,7 @@ impl<'a> PathTransform<'a> {
108
110
Some ( hir:: GenericDef :: Trait ( _) ) => 1 ,
109
111
_ => 0 ,
110
112
} ;
111
- let type_substs : FxHashMap < _ , _ > = self
113
+ let type_and_const_substs : FxHashMap < _ , _ > = self
112
114
. generic_def
113
115
. into_iter ( )
114
116
. flat_map ( |it| it. type_params ( db) )
@@ -119,19 +121,17 @@ impl<'a> PathTransform<'a> {
119
121
// can still hit those trailing values and check if they actually have
120
122
// a default type. If they do, go for that type from `hir` to `ast` so
121
123
// the resulting change can be applied correctly.
122
- . zip ( self . substs . types . iter ( ) . map ( Some ) . chain ( std:: iter:: repeat ( None ) ) )
123
- . filter_map ( |( k, v) | match k. split ( db) {
124
- Either :: Left ( _) => None , // FIXME: map const types too
125
- Either :: Right ( t) => match v {
126
- Some ( v) => Some ( ( k, v. ty ( ) ?. clone ( ) ) ) ,
127
- None => {
128
- let default = t. default ( db) ?;
129
- let v = ast:: make:: ty (
130
- & default. display_source_code ( db, source_module. into ( ) , false ) . ok ( ) ?,
131
- ) ;
132
- Some ( ( k, v) )
133
- }
134
- } ,
124
+ . zip ( self . substs . types_and_consts . iter ( ) . map ( Some ) . chain ( std:: iter:: repeat ( None ) ) )
125
+ . filter_map ( |( k, v) | match ( k. split ( db) , v) {
126
+ ( _, Some ( v) ) => Some ( ( k, v. ty ( ) ?. clone ( ) ) ) ,
127
+ ( Either :: Right ( t) , None ) => {
128
+ let default = t. default ( db) ?;
129
+ let v = ast:: make:: ty (
130
+ & default. display_source_code ( db, source_module. into ( ) , false ) . ok ( ) ?,
131
+ ) ;
132
+ Some ( ( k, v) )
133
+ }
134
+ ( Either :: Left ( _) , None ) => None , // FIXME: get default const value
135
135
} )
136
136
. collect ( ) ;
137
137
let lifetime_substs: FxHashMap < _ , _ > = self
@@ -141,12 +141,17 @@ impl<'a> PathTransform<'a> {
141
141
. zip ( self . substs . lifetimes . clone ( ) )
142
142
. filter_map ( |( k, v) | Some ( ( k. name ( db) . display ( db. upcast ( ) ) . to_string ( ) , v. lifetime ( ) ?) ) )
143
143
. collect ( ) ;
144
- Ctx { type_substs, lifetime_substs, target_module, source_scope : self . source_scope }
144
+ Ctx {
145
+ type_and_const_substs,
146
+ lifetime_substs,
147
+ target_module,
148
+ source_scope : self . source_scope ,
149
+ }
145
150
}
146
151
}
147
152
148
153
struct Ctx < ' a > {
149
- type_substs : FxHashMap < hir:: TypeOrConstParam , ast:: Type > ,
154
+ type_and_const_substs : FxHashMap < hir:: TypeOrConstParam , ast:: Type > ,
150
155
lifetime_substs : FxHashMap < LifetimeName , ast:: Lifetime > ,
151
156
target_module : hir:: Module ,
152
157
source_scope : & ' a SemanticsScope < ' a > ,
@@ -203,7 +208,7 @@ impl<'a> Ctx<'a> {
203
208
204
209
match resolution {
205
210
hir:: PathResolution :: TypeParam ( tp) => {
206
- if let Some ( subst) = self . type_substs . get ( & tp. merge ( ) ) {
211
+ if let Some ( subst) = self . type_and_const_substs . get ( & tp. merge ( ) ) {
207
212
let parent = path. syntax ( ) . parent ( ) ?;
208
213
if let Some ( parent) = ast:: Path :: cast ( parent. clone ( ) ) {
209
214
// Path inside path means that there is an associated
@@ -270,8 +275,12 @@ impl<'a> Ctx<'a> {
270
275
}
271
276
ted:: replace ( path. syntax ( ) , res. syntax ( ) )
272
277
}
278
+ hir:: PathResolution :: ConstParam ( cp) => {
279
+ if let Some ( subst) = self . type_and_const_substs . get ( & cp. merge ( ) ) {
280
+ ted:: replace ( path. syntax ( ) , subst. clone_subtree ( ) . clone_for_update ( ) . syntax ( ) ) ;
281
+ }
282
+ }
273
283
hir:: PathResolution :: Local ( _)
274
- | hir:: PathResolution :: ConstParam ( _)
275
284
| hir:: PathResolution :: SelfType ( _)
276
285
| hir:: PathResolution :: Def ( _)
277
286
| hir:: PathResolution :: BuiltinAttr ( _)
@@ -298,9 +307,14 @@ fn get_syntactic_substs(impl_def: ast::Impl) -> Option<AstSubsts> {
298
307
fn get_type_args_from_arg_list ( generic_arg_list : ast:: GenericArgList ) -> Option < AstSubsts > {
299
308
let mut result = AstSubsts :: default ( ) ;
300
309
generic_arg_list. generic_args ( ) . for_each ( |generic_arg| match generic_arg {
301
- ast:: GenericArg :: TypeArg ( type_arg) => result. types . push ( type_arg) ,
310
+ // Const params are marked as consts on definition only,
311
+ // being passed to the trait they are indistguishable from type params;
312
+ // anyway, we don't really need to distinguish them here.
313
+ ast:: GenericArg :: TypeArg ( type_or_const_arg) => {
314
+ result. types_and_consts . push ( type_or_const_arg)
315
+ }
302
316
ast:: GenericArg :: LifetimeArg ( l_arg) => result. lifetimes . push ( l_arg) ,
303
- _ => ( ) , // FIXME: don't filter out const params
317
+ _ => ( ) ,
304
318
} ) ;
305
319
306
320
Some ( result)
0 commit comments