mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
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 <joshmcg88@gmail.com>
This commit is contained in:
commit
bf3a8eb40a
@ -26,7 +26,7 @@ use crate::{
|
|||||||
render::{
|
render::{
|
||||||
const_::render_const,
|
const_::render_const,
|
||||||
enum_variant::render_variant,
|
enum_variant::render_variant,
|
||||||
function::render_fn,
|
function::{render_fn, render_method},
|
||||||
macro_::render_macro,
|
macro_::render_macro,
|
||||||
pattern::{render_struct_pat, render_variant_pat},
|
pattern::{render_struct_pat, render_variant_pat},
|
||||||
render_field, render_resolution, render_tuple_field,
|
render_field, render_resolution, render_tuple_field,
|
||||||
@ -123,6 +123,17 @@ impl Completions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn add_method(
|
||||||
|
&mut self,
|
||||||
|
ctx: &CompletionContext,
|
||||||
|
func: hir::Function,
|
||||||
|
local_name: Option<String>,
|
||||||
|
) {
|
||||||
|
if let Some(item) = render_method(RenderContext::new(ctx), None, local_name, func) {
|
||||||
|
self.add(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn add_variant_pat(
|
pub(crate) fn add_variant_pat(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &CompletionContext,
|
ctx: &CompletionContext,
|
||||||
|
@ -51,7 +51,7 @@ fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: &T
|
|||||||
&& ctx.scope.module().map_or(true, |m| func.is_visible_from(ctx.db, m))
|
&& ctx.scope.module().map_or(true, |m| func.is_visible_from(ctx.db, m))
|
||||||
&& seen_methods.insert(func.name(ctx.db))
|
&& seen_methods.insert(func.name(ctx.db))
|
||||||
{
|
{
|
||||||
acc.add_function(ctx, func, None);
|
acc.add_method(ctx, func, None);
|
||||||
}
|
}
|
||||||
None::<()>
|
None::<()>
|
||||||
});
|
});
|
||||||
|
@ -148,8 +148,10 @@ impl<'a> Render<'a> {
|
|||||||
..CompletionRelevance::default()
|
..CompletionRelevance::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(ref_match) = compute_ref_match(self.ctx.completion, ty) {
|
if let Some(_ref_match) = compute_ref_match(self.ctx.completion, ty) {
|
||||||
item.ref_match(ref_match);
|
// FIXME
|
||||||
|
// For now we don't properly calculate the edits for ref match
|
||||||
|
// completions on struct fields, so we've disabled them. See #8058.
|
||||||
}
|
}
|
||||||
|
|
||||||
item.build()
|
item.build()
|
||||||
@ -1313,4 +1315,42 @@ fn main() {
|
|||||||
"#]],
|
"#]],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn struct_field_method_ref() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
struct Foo { bar: u32 }
|
||||||
|
impl Foo { fn baz(&self) -> u32 { 0 } }
|
||||||
|
|
||||||
|
fn foo(f: Foo) { let _: &u32 = f.b$0 }
|
||||||
|
"#,
|
||||||
|
// FIXME
|
||||||
|
// Ideally we'd also suggest &f.bar and &f.baz() as exact
|
||||||
|
// type matches. See #8058.
|
||||||
|
expect![[r#"
|
||||||
|
[
|
||||||
|
CompletionItem {
|
||||||
|
label: "bar",
|
||||||
|
source_range: 98..99,
|
||||||
|
delete: 98..99,
|
||||||
|
insert: "bar",
|
||||||
|
kind: SymbolKind(
|
||||||
|
Field,
|
||||||
|
),
|
||||||
|
detail: "u32",
|
||||||
|
},
|
||||||
|
CompletionItem {
|
||||||
|
label: "baz()",
|
||||||
|
source_range: 98..99,
|
||||||
|
delete: 98..99,
|
||||||
|
insert: "baz()$0",
|
||||||
|
kind: Method,
|
||||||
|
lookup: "baz",
|
||||||
|
detail: "fn(&self) -> u32",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,17 @@ pub(crate) fn render_fn<'a>(
|
|||||||
fn_: hir::Function,
|
fn_: hir::Function,
|
||||||
) -> Option<CompletionItem> {
|
) -> Option<CompletionItem> {
|
||||||
let _p = profile::span("render_fn");
|
let _p = profile::span("render_fn");
|
||||||
Some(FunctionRender::new(ctx, local_name, fn_)?.render(import_to_add))
|
Some(FunctionRender::new(ctx, local_name, fn_, false)?.render(import_to_add))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn render_method<'a>(
|
||||||
|
ctx: RenderContext<'a>,
|
||||||
|
import_to_add: Option<ImportEdit>,
|
||||||
|
local_name: Option<String>,
|
||||||
|
fn_: hir::Function,
|
||||||
|
) -> Option<CompletionItem> {
|
||||||
|
let _p = profile::span("render_method");
|
||||||
|
Some(FunctionRender::new(ctx, local_name, fn_, true)?.render(import_to_add))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -29,6 +39,7 @@ struct FunctionRender<'a> {
|
|||||||
name: String,
|
name: String,
|
||||||
func: hir::Function,
|
func: hir::Function,
|
||||||
ast_node: Fn,
|
ast_node: Fn,
|
||||||
|
is_method: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FunctionRender<'a> {
|
impl<'a> FunctionRender<'a> {
|
||||||
@ -36,11 +47,12 @@ impl<'a> FunctionRender<'a> {
|
|||||||
ctx: RenderContext<'a>,
|
ctx: RenderContext<'a>,
|
||||||
local_name: Option<String>,
|
local_name: Option<String>,
|
||||||
fn_: hir::Function,
|
fn_: hir::Function,
|
||||||
|
is_method: bool,
|
||||||
) -> Option<FunctionRender<'a>> {
|
) -> Option<FunctionRender<'a>> {
|
||||||
let name = local_name.unwrap_or_else(|| fn_.name(ctx.db()).to_string());
|
let name = local_name.unwrap_or_else(|| fn_.name(ctx.db()).to_string());
|
||||||
let ast_node = fn_.source(ctx.db())?.value;
|
let ast_node = fn_.source(ctx.db())?.value;
|
||||||
|
|
||||||
Some(FunctionRender { ctx, name, func: fn_, ast_node })
|
Some(FunctionRender { ctx, name, func: fn_, ast_node, is_method })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(self, import_to_add: Option<ImportEdit>) -> CompletionItem {
|
fn render(self, import_to_add: Option<ImportEdit>) -> CompletionItem {
|
||||||
@ -67,7 +79,12 @@ impl<'a> FunctionRender<'a> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if let Some(ref_match) = compute_ref_match(self.ctx.completion, &ret_type) {
|
if let Some(ref_match) = compute_ref_match(self.ctx.completion, &ret_type) {
|
||||||
item.ref_match(ref_match);
|
// FIXME
|
||||||
|
// For now we don't properly calculate the edits for ref match
|
||||||
|
// completions on methods, so we've disabled them. See #8058.
|
||||||
|
if !self.is_method {
|
||||||
|
item.ref_match(ref_match);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
item.build()
|
item.build()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user