aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_completion/src')
-rw-r--r--crates/ide_completion/src/completions.rs13
-rw-r--r--crates/ide_completion/src/completions/attribute.rs3
-rw-r--r--crates/ide_completion/src/completions/dot.rs2
-rw-r--r--crates/ide_completion/src/render.rs44
-rw-r--r--crates/ide_completion/src/render/function.rs23
5 files changed, 77 insertions, 8 deletions
diff --git a/crates/ide_completion/src/completions.rs b/crates/ide_completion/src/completions.rs
index cdac4e41a..6d572a836 100644
--- a/crates/ide_completion/src/completions.rs
+++ b/crates/ide_completion/src/completions.rs
@@ -26,7 +26,7 @@ use crate::{
26 render::{ 26 render::{
27 const_::render_const, 27 const_::render_const,
28 enum_variant::render_variant, 28 enum_variant::render_variant,
29 function::render_fn, 29 function::{render_fn, render_method},
30 macro_::render_macro, 30 macro_::render_macro,
31 pattern::{render_struct_pat, render_variant_pat}, 31 pattern::{render_struct_pat, render_variant_pat},
32 render_field, render_resolution, render_tuple_field, 32 render_field, render_resolution, render_tuple_field,
@@ -123,6 +123,17 @@ impl Completions {
123 } 123 }
124 } 124 }
125 125
126 pub(crate) fn add_method(
127 &mut self,
128 ctx: &CompletionContext,
129 func: hir::Function,
130 local_name: Option<String>,
131 ) {
132 if let Some(item) = render_method(RenderContext::new(ctx), None, local_name, func) {
133 self.add(item)
134 }
135 }
136
126 pub(crate) fn add_variant_pat( 137 pub(crate) fn add_variant_pat(
127 &mut self, 138 &mut self,
128 ctx: &CompletionContext, 139 ctx: &CompletionContext,
diff --git a/crates/ide_completion/src/completions/attribute.rs b/crates/ide_completion/src/completions/attribute.rs
index e846678b4..b1505c74b 100644
--- a/crates/ide_completion/src/completions/attribute.rs
+++ b/crates/ide_completion/src/completions/attribute.rs
@@ -246,7 +246,8 @@ fn get_derive_names_in_scope(ctx: &CompletionContext) -> FxHashSet<String> {
246 let mut result = FxHashSet::default(); 246 let mut result = FxHashSet::default();
247 ctx.scope.process_all_names(&mut |name, scope_def| { 247 ctx.scope.process_all_names(&mut |name, scope_def| {
248 if let hir::ScopeDef::MacroDef(mac) = scope_def { 248 if let hir::ScopeDef::MacroDef(mac) = scope_def {
249 if mac.is_derive_macro() { 249 // FIXME kind() doesn't check whether proc-macro is a derive
250 if mac.kind() == hir::MacroKind::Derive || mac.kind() == hir::MacroKind::ProcMacro {
250 result.insert(name.to_string()); 251 result.insert(name.to_string());
251 } 252 }
252 } 253 }
diff --git a/crates/ide_completion/src/completions/dot.rs b/crates/ide_completion/src/completions/dot.rs
index cec2d0c3a..7e4efe589 100644
--- a/crates/ide_completion/src/completions/dot.rs
+++ b/crates/ide_completion/src/completions/dot.rs
@@ -51,7 +51,7 @@ fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: &T
51 && ctx.scope.module().map_or(true, |m| func.is_visible_from(ctx.db, m)) 51 && ctx.scope.module().map_or(true, |m| func.is_visible_from(ctx.db, m))
52 && seen_methods.insert(func.name(ctx.db)) 52 && seen_methods.insert(func.name(ctx.db))
53 { 53 {
54 acc.add_function(ctx, func, None); 54 acc.add_method(ctx, func, None);
55 } 55 }
56 None::<()> 56 None::<()>
57 }); 57 });
diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs
index 23e00aa47..9ce49074f 100644
--- a/crates/ide_completion/src/render.rs
+++ b/crates/ide_completion/src/render.rs
@@ -148,8 +148,10 @@ impl<'a> Render<'a> {
148 ..CompletionRelevance::default() 148 ..CompletionRelevance::default()
149 }); 149 });
150 150
151 if let Some(ref_match) = compute_ref_match(self.ctx.completion, ty) { 151 if let Some(_ref_match) = compute_ref_match(self.ctx.completion, ty) {
152 item.ref_match(ref_match); 152 // FIXME
153 // For now we don't properly calculate the edits for ref match
154 // completions on struct fields, so we've disabled them. See #8058.
153 } 155 }
154 156
155 item.build() 157 item.build()
@@ -1313,4 +1315,42 @@ fn main() {
1313 "#]], 1315 "#]],
1314 ) 1316 )
1315 } 1317 }
1318
1319 #[test]
1320 fn struct_field_method_ref() {
1321 check(
1322 r#"
1323struct Foo { bar: u32 }
1324impl Foo { fn baz(&self) -> u32 { 0 } }
1325
1326fn foo(f: Foo) { let _: &u32 = f.b$0 }
1327"#,
1328 // FIXME
1329 // Ideally we'd also suggest &f.bar and &f.baz() as exact
1330 // type matches. See #8058.
1331 expect![[r#"
1332 [
1333 CompletionItem {
1334 label: "bar",
1335 source_range: 98..99,
1336 delete: 98..99,
1337 insert: "bar",
1338 kind: SymbolKind(
1339 Field,
1340 ),
1341 detail: "u32",
1342 },
1343 CompletionItem {
1344 label: "baz()",
1345 source_range: 98..99,
1346 delete: 98..99,
1347 insert: "baz()$0",
1348 kind: Method,
1349 lookup: "baz",
1350 detail: "fn(&self) -> u32",
1351 },
1352 ]
1353 "#]],
1354 );
1355 }
1316} 1356}
diff --git a/crates/ide_completion/src/render/function.rs b/crates/ide_completion/src/render/function.rs
index 010303182..b1eba20e8 100644
--- a/crates/ide_completion/src/render/function.rs
+++ b/crates/ide_completion/src/render/function.rs
@@ -20,7 +20,17 @@ pub(crate) fn render_fn<'a>(
20 fn_: hir::Function, 20 fn_: hir::Function,
21) -> Option<CompletionItem> { 21) -> Option<CompletionItem> {
22 let _p = profile::span("render_fn"); 22 let _p = profile::span("render_fn");
23 Some(FunctionRender::new(ctx, local_name, fn_)?.render(import_to_add)) 23 Some(FunctionRender::new(ctx, local_name, fn_, false)?.render(import_to_add))
24}
25
26pub(crate) fn render_method<'a>(
27 ctx: RenderContext<'a>,
28 import_to_add: Option<ImportEdit>,
29 local_name: Option<String>,
30 fn_: hir::Function,
31) -> Option<CompletionItem> {
32 let _p = profile::span("render_method");
33 Some(FunctionRender::new(ctx, local_name, fn_, true)?.render(import_to_add))
24} 34}
25 35
26#[derive(Debug)] 36#[derive(Debug)]
@@ -29,6 +39,7 @@ struct FunctionRender<'a> {
29 name: String, 39 name: String,
30 func: hir::Function, 40 func: hir::Function,
31 ast_node: Fn, 41 ast_node: Fn,
42 is_method: bool,
32} 43}
33 44
34impl<'a> FunctionRender<'a> { 45impl<'a> FunctionRender<'a> {
@@ -36,11 +47,12 @@ impl<'a> FunctionRender<'a> {
36 ctx: RenderContext<'a>, 47 ctx: RenderContext<'a>,
37 local_name: Option<String>, 48 local_name: Option<String>,
38 fn_: hir::Function, 49 fn_: hir::Function,
50 is_method: bool,
39 ) -> Option<FunctionRender<'a>> { 51 ) -> Option<FunctionRender<'a>> {
40 let name = local_name.unwrap_or_else(|| fn_.name(ctx.db()).to_string()); 52 let name = local_name.unwrap_or_else(|| fn_.name(ctx.db()).to_string());
41 let ast_node = fn_.source(ctx.db())?.value; 53 let ast_node = fn_.source(ctx.db())?.value;
42 54
43 Some(FunctionRender { ctx, name, func: fn_, ast_node }) 55 Some(FunctionRender { ctx, name, func: fn_, ast_node, is_method })
44 } 56 }
45 57
46 fn render(self, import_to_add: Option<ImportEdit>) -> CompletionItem { 58 fn render(self, import_to_add: Option<ImportEdit>) -> CompletionItem {
@@ -67,7 +79,12 @@ impl<'a> FunctionRender<'a> {
67 }); 79 });
68 80
69 if let Some(ref_match) = compute_ref_match(self.ctx.completion, &ret_type) { 81 if let Some(ref_match) = compute_ref_match(self.ctx.completion, &ret_type) {
70 item.ref_match(ref_match); 82 // FIXME
83 // For now we don't properly calculate the edits for ref match
84 // completions on methods, so we've disabled them. See #8058.
85 if !self.is_method {
86 item.ref_match(ref_match);
87 }
71 } 88 }
72 89
73 item.build() 90 item.build()