aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_assists/src/assists/add_missing_impl_members.rs21
-rw-r--r--crates/ra_syntax/src/ast/make.rs7
2 files changed, 19 insertions, 9 deletions
diff --git a/crates/ra_assists/src/assists/add_missing_impl_members.rs b/crates/ra_assists/src/assists/add_missing_impl_members.rs
index dd62b1b78..7b50fb422 100644
--- a/crates/ra_assists/src/assists/add_missing_impl_members.rs
+++ b/crates/ra_assists/src/assists/add_missing_impl_members.rs
@@ -156,13 +156,13 @@ fn add_missing_impl_members_inner(
156 .collect(); 156 .collect();
157 let items = missing_items 157 let items = missing_items
158 .into_iter() 158 .into_iter()
159 .map(|it| {
160 substitute_type_params(db, hir::InFile::new(file_id.into(), it), &substs_by_param)
161 })
159 .map(|it| match module { 162 .map(|it| match module {
160 Some(module) => qualify_paths(db, hir::InFile::new(file_id.into(), it), module), 163 Some(module) => qualify_paths(db, hir::InFile::new(file_id.into(), it), module),
161 None => it, 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 .map(|it| match it { 166 .map(|it| match it {
167 ast::ImplItem::FnDef(def) => ast::ImplItem::FnDef(add_body(def)), 167 ast::ImplItem::FnDef(def) => ast::ImplItem::FnDef(add_body(def)),
168 _ => it, 168 _ => it,
@@ -239,11 +239,9 @@ fn substitute_type_params<N: AstNode>(
239 239
240use hir::PathResolution; 240use hir::PathResolution;
241 241
242// TODO handle generic args
243// TODO handle associated item paths
244// TODO handle value ns?
245
246// FIXME extract this to a general utility as well 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
247fn qualify_paths<N: AstNode>(db: &impl HirDatabase, node: hir::InFile<N>, from: hir::Module) -> N { 245fn qualify_paths<N: AstNode>(db: &impl HirDatabase, node: hir::InFile<N>, from: hir::Module) -> N {
248 let path_replacements = node 246 let path_replacements = node
249 .value 247 .value
@@ -255,12 +253,17 @@ fn qualify_paths<N: AstNode>(db: &impl HirDatabase, node: hir::InFile<N>, from:
255 // don't try to qualify `Fn(Foo) -> Bar` paths, they are in prelude anyway 253 // don't try to qualify `Fn(Foo) -> Bar` paths, they are in prelude anyway
256 return None; 254 return None;
257 } 255 }
256 // FIXME check if some ancestor is already being replaced, if so skip this
258 let analyzer = hir::SourceAnalyzer::new(db, node.with_value(p.syntax()), None); 257 let analyzer = hir::SourceAnalyzer::new(db, node.with_value(p.syntax()), None);
259 let resolution = analyzer.resolve_path(db, &p)?; 258 let resolution = analyzer.resolve_path(db, &p)?;
260 match resolution { 259 match resolution {
261 PathResolution::Def(def) => { 260 PathResolution::Def(def) => {
262 let found_path = from.find_path(db, def)?; 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 PathResolution::Local(_) 268 PathResolution::Local(_)
266 | PathResolution::TypeParam(_) 269 | PathResolution::TypeParam(_)
@@ -535,7 +538,7 @@ impl foo::Foo for S { <|> }",
535 " 538 "
536mod foo { 539mod foo {
537 pub struct Bar<T>; 540 pub struct Bar<T>;
538 impl Bar { type Assoc = u32; } 541 impl Bar<T> { type Assoc = u32; }
539 trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); } 542 trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); }
540} 543}
541struct S; 544struct S;
diff --git a/crates/ra_syntax/src/ast/make.rs b/crates/ra_syntax/src/ast/make.rs
index 04a5408fe..68d64a0cc 100644
--- a/crates/ra_syntax/src/ast/make.rs
+++ b/crates/ra_syntax/src/ast/make.rs
@@ -21,6 +21,13 @@ pub fn path_qualified(qual: ast::Path, name_ref: ast::NameRef) -> ast::Path {
21fn path_from_text(text: &str) -> ast::Path { 21fn path_from_text(text: &str) -> ast::Path {
22 ast_from_text(text) 22 ast_from_text(text)
23} 23}
24pub fn path_with_type_arg_list(path: ast::Path, args: Option<ast::TypeArgList>) -> ast::Path {
25 if let Some(args) = args {
26 ast_from_text(&format!("const X: {}{}", path.syntax(), args.syntax()))
27 } else {
28 path
29 }
30}
24 31
25pub fn record_field(name: ast::NameRef, expr: Option<ast::Expr>) -> ast::RecordField { 32pub fn record_field(name: ast::NameRef, expr: Option<ast::Expr>) -> ast::RecordField {
26 return match expr { 33 return match expr {