aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/ast_transform.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists/src/ast_transform.rs')
-rw-r--r--crates/ra_assists/src/ast_transform.rs26
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.
2use rustc_hash::FxHashMap; 2use rustc_hash::FxHashMap;
3 3
4use hir::{PathResolution, SemanticsScope}; 4use hir::{HirDisplay, PathResolution, SemanticsScope};
5use ra_ide_db::RootDatabase; 5use ra_ide_db::RootDatabase;
6use ra_syntax::{ 6use 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 {