@@ -11,7 +11,9 @@ use syntax::{
1111
1212#[ derive( Default ) ]
1313struct 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 > ,
1517 lifetimes : Vec < ast:: LifetimeArg > ,
1618}
1719
@@ -108,7 +110,7 @@ impl<'a> PathTransform<'a> {
108110 Some ( hir:: GenericDef :: Trait ( _) ) => 1 ,
109111 _ => 0 ,
110112 } ;
111- let type_substs : FxHashMap < _ , _ > = self
113+ let type_and_const_substs : FxHashMap < _ , _ > = self
112114 . generic_def
113115 . into_iter ( )
114116 . flat_map ( |it| it. type_params ( db) )
@@ -119,19 +121,17 @@ impl<'a> PathTransform<'a> {
119121 // can still hit those trailing values and check if they actually have
120122 // a default type. If they do, go for that type from `hir` to `ast` so
121123 // 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
135135 } )
136136 . collect ( ) ;
137137 let lifetime_substs: FxHashMap < _ , _ > = self
@@ -141,12 +141,17 @@ impl<'a> PathTransform<'a> {
141141 . zip ( self . substs . lifetimes . clone ( ) )
142142 . filter_map ( |( k, v) | Some ( ( k. name ( db) . display ( db. upcast ( ) ) . to_string ( ) , v. lifetime ( ) ?) ) )
143143 . 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+ }
145150 }
146151}
147152
148153struct Ctx < ' a > {
149- type_substs : FxHashMap < hir:: TypeOrConstParam , ast:: Type > ,
154+ type_and_const_substs : FxHashMap < hir:: TypeOrConstParam , ast:: Type > ,
150155 lifetime_substs : FxHashMap < LifetimeName , ast:: Lifetime > ,
151156 target_module : hir:: Module ,
152157 source_scope : & ' a SemanticsScope < ' a > ,
@@ -203,7 +208,7 @@ impl<'a> Ctx<'a> {
203208
204209 match resolution {
205210 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 ( ) ) {
207212 let parent = path. syntax ( ) . parent ( ) ?;
208213 if let Some ( parent) = ast:: Path :: cast ( parent. clone ( ) ) {
209214 // Path inside path means that there is an associated
@@ -270,8 +275,12 @@ impl<'a> Ctx<'a> {
270275 }
271276 ted:: replace ( path. syntax ( ) , res. syntax ( ) )
272277 }
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+ }
273283 hir:: PathResolution :: Local ( _)
274- | hir:: PathResolution :: ConstParam ( _)
275284 | hir:: PathResolution :: SelfType ( _)
276285 | hir:: PathResolution :: Def ( _)
277286 | hir:: PathResolution :: BuiltinAttr ( _)
@@ -298,9 +307,14 @@ fn get_syntactic_substs(impl_def: ast::Impl) -> Option<AstSubsts> {
298307fn get_type_args_from_arg_list ( generic_arg_list : ast:: GenericArgList ) -> Option < AstSubsts > {
299308 let mut result = AstSubsts :: default ( ) ;
300309 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+ }
302316 ast:: GenericArg :: LifetimeArg ( l_arg) => result. lifetimes . push ( l_arg) ,
303- _ => ( ) , // FIXME: don't filter out const params
317+ _ => ( ) ,
304318 } ) ;
305319
306320 Some ( result)
0 commit comments