diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-03-23 09:24:26 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2021-03-23 09:24:26 +0000 |
commit | bf3a8eb40a1c684ffc9cb40477558ec276253c3b (patch) | |
tree | 11980d33f4b957019df0a6172c26446e4a4783c0 /crates/ide_completion/src | |
parent | 4b997b86633b1c0ca134d89e8236d285422c04e3 (diff) | |
parent | 18c3fb2df549da2d51104d74107d3b8cd27ee996 (diff) |
Merge #8142
8142: temp disable broken ref match completions for struct fields/methods r=matklad a=JoshMcguigan
This PR implements a temporary workaround for #8058 by disabling ref match completions for struct fields and methods. Disabling this doesn't break any existing functionality (that I am aware of) since these completions were broken.
I plan to keep working on a real fix for the underlying issue here, but I think a proper fix could take some time, so I'd prefer to quickly fix the bug to buy some more time to implement a better solution (which would ultimately allow re-enabling ref matches for struct fields and methods).
Co-authored-by: Josh Mcguigan <[email protected]>
Diffstat (limited to 'crates/ide_completion/src')
-rw-r--r-- | crates/ide_completion/src/completions.rs | 13 | ||||
-rw-r--r-- | crates/ide_completion/src/completions/dot.rs | 2 | ||||
-rw-r--r-- | crates/ide_completion/src/render.rs | 44 | ||||
-rw-r--r-- | crates/ide_completion/src/render/function.rs | 23 |
4 files changed, 75 insertions, 7 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/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#" | ||
1323 | struct Foo { bar: u32 } | ||
1324 | impl Foo { fn baz(&self) -> u32 { 0 } } | ||
1325 | |||
1326 | fn 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 | |||
26 | pub(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 | ||
34 | impl<'a> FunctionRender<'a> { | 45 | impl<'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() |