diff options
Diffstat (limited to 'crates/ra_assists/src/ast_transform.rs')
-rw-r--r-- | crates/ra_assists/src/ast_transform.rs | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/crates/ra_assists/src/ast_transform.rs b/crates/ra_assists/src/ast_transform.rs index 52b4c82db..3079a02a2 100644 --- a/crates/ra_assists/src/ast_transform.rs +++ b/crates/ra_assists/src/ast_transform.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | //! `AstTransformer`s are functions that replace nodes in an AST and can be easily combined. | 1 | //! `AstTransformer`s are functions that replace nodes in an AST and can be easily combined. |
2 | use rustc_hash::FxHashMap; | 2 | use rustc_hash::FxHashMap; |
3 | 3 | ||
4 | use hir::{PathResolution, SemanticsScope}; | 4 | use hir::{HirDisplay, PathResolution, SemanticsScope}; |
5 | use ra_ide_db::RootDatabase; | 5 | use ra_ide_db::RootDatabase; |
6 | use ra_syntax::{ | 6 | use ra_syntax::{ |
7 | algo::SyntaxRewriter, | 7 | algo::SyntaxRewriter, |
@@ -51,7 +51,27 @@ impl<'a> SubstituteTypeParams<'a> { | |||
51 | .into_iter() | 51 | .into_iter() |
52 | // this is a trait impl, so we need to skip the first type parameter -- this is a bit hacky | 52 | // this is a trait impl, so we need to skip the first type parameter -- this is a bit hacky |
53 | .skip(1) | 53 | .skip(1) |
54 | .zip(substs.into_iter()) | 54 | // The actual list of trait type parameters may be longer than the one |
55 | // used in the `impl` block due to trailing default type parametrs. | ||
56 | // For that case we extend the `substs` with an empty iterator so we | ||
57 | // can still hit those trailing values and check if they actually have | ||
58 | // a default type. If they do, go for that type from `hir` to `ast` so | ||
59 | // the resulting change can be applied correctly. | ||
60 | .zip(substs.into_iter().map(Some).chain(std::iter::repeat(None))) | ||
61 | .filter_map(|(k, v)| match v { | ||
62 | Some(v) => Some((k, v)), | ||
63 | None => { | ||
64 | let default = k.default(source_scope.db)?; | ||
65 | Some(( | ||
66 | k, | ||
67 | ast::make::type_ref( | ||
68 | &default | ||
69 | .display_source_code(source_scope.db, source_scope.module()?.into()) | ||
70 | .ok()?, | ||
71 | ), | ||
72 | )) | ||
73 | } | ||
74 | }) | ||
55 | .collect(); | 75 | .collect(); |
56 | return SubstituteTypeParams { | 76 | return SubstituteTypeParams { |
57 | source_scope, | 77 | source_scope, |
@@ -85,6 +105,7 @@ impl<'a> SubstituteTypeParams<'a> { | |||
85 | ast::TypeRef::PathType(path_type) => path_type.path()?, | 105 | ast::TypeRef::PathType(path_type) => path_type.path()?, |
86 | _ => return None, | 106 | _ => return None, |
87 | }; | 107 | }; |
108 | // FIXME: use `hir::Path::from_src` instead. | ||
88 | let path = hir::Path::from_ast(path)?; | 109 | let path = hir::Path::from_ast(path)?; |
89 | let resolution = self.source_scope.resolve_hir_path(&path)?; | 110 | let resolution = self.source_scope.resolve_hir_path(&path)?; |
90 | match resolution { | 111 | match resolution { |
@@ -128,6 +149,7 @@ impl<'a> QualifyPaths<'a> { | |||
128 | // don't try to qualify `Fn(Foo) -> Bar` paths, they are in prelude anyway | 149 | // don't try to qualify `Fn(Foo) -> Bar` paths, they are in prelude anyway |
129 | return None; | 150 | return None; |
130 | } | 151 | } |
152 | // FIXME: use `hir::Path::from_src` instead. | ||
131 | let hir_path = hir::Path::from_ast(p.clone()); | 153 | let hir_path = hir::Path::from_ast(p.clone()); |
132 | let resolution = self.source_scope.resolve_hir_path(&hir_path?)?; | 154 | let resolution = self.source_scope.resolve_hir_path(&hir_path?)?; |
133 | match resolution { | 155 | match resolution { |