@@ -156,13 +156,13 @@ fn add_missing_impl_members_inner(
156
156
. collect ( ) ;
157
157
let items = missing_items
158
158
. into_iter ( )
159
+ . map ( |it| {
160
+ substitute_type_params ( db, hir:: InFile :: new ( file_id. into ( ) , it) , & substs_by_param)
161
+ } )
159
162
. map ( |it| match module {
160
163
Some ( module) => qualify_paths ( db, hir:: InFile :: new ( file_id. into ( ) , it) , module) ,
161
164
None => it,
162
165
} )
163
- . map ( |it| {
164
- substitute_type_params ( db, hir:: InFile :: new ( file_id. into ( ) , it) , & substs_by_param)
165
- } )
166
166
. map ( |it| match it {
167
167
ast:: ImplItem :: FnDef ( def) => ast:: ImplItem :: FnDef ( add_body ( def) ) ,
168
168
_ => it,
@@ -239,11 +239,9 @@ fn substitute_type_params<N: AstNode>(
239
239
240
240
use hir:: PathResolution ;
241
241
242
- // TODO handle generic args
243
- // TODO handle associated item paths
244
- // TODO handle value ns?
245
-
246
242
// FIXME extract this to a general utility as well
243
+ // FIXME handle value ns?
244
+ // FIXME this doesn't 'commute' with `substitute_type_params`, since type params in newly generated type arg lists don't resolve. Currently we can avoid this problem, but it's worth thinking about a solution
247
245
fn qualify_paths < N : AstNode > ( db : & impl HirDatabase , node : hir:: InFile < N > , from : hir:: Module ) -> N {
248
246
let path_replacements = node
249
247
. value
@@ -255,12 +253,17 @@ fn qualify_paths<N: AstNode>(db: &impl HirDatabase, node: hir::InFile<N>, from:
255
253
// don't try to qualify `Fn(Foo) -> Bar` paths, they are in prelude anyway
256
254
return None ;
257
255
}
256
+ // FIXME check if some ancestor is already being replaced, if so skip this
258
257
let analyzer = hir:: SourceAnalyzer :: new ( db, node. with_value ( p. syntax ( ) ) , None ) ;
259
258
let resolution = analyzer. resolve_path ( db, & p) ?;
260
259
match resolution {
261
260
PathResolution :: Def ( def) => {
262
261
let found_path = from. find_path ( db, def) ?;
263
- Some ( ( p, found_path. to_ast ( ) ) )
262
+ let args = p
263
+ . segment ( )
264
+ . and_then ( |s| s. type_arg_list ( ) )
265
+ . map ( |arg_list| qualify_paths ( db, node. with_value ( arg_list) , from) ) ;
266
+ Some ( ( p, make:: path_with_type_arg_list ( found_path. to_ast ( ) , args) ) )
264
267
}
265
268
PathResolution :: Local ( _)
266
269
| PathResolution :: TypeParam ( _)
@@ -535,7 +538,7 @@ impl foo::Foo for S { <|> }",
535
538
"
536
539
mod foo {
537
540
pub struct Bar<T>;
538
- impl Bar { type Assoc = u32; }
541
+ impl Bar<T> { type Assoc = u32; }
539
542
trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); }
540
543
}
541
544
struct S;
0 commit comments