Skip to content

Reference completions are a bit too aggressive #8357

Closed
@Lucretiel

Description

@Lucretiel

When I go to complete this function:

fn poll(&mut self, value: &mut Context);

future.poll(&mut  )
//               ^ The point is here

I see these completions:

Screen Shot 2021-04-05 at 3 41 17 PM

&mut context definitely seems like the one I want. However, when I select it, it doesn't seem to be aware that I already typed &mut, and inserts it again:

future.poll(&mut &mut context)

This completion should be sufficiently context-sensitive that it doesn't double up the &mut prefix.

Activity

added
S-actionableSomeone could pick this issue up and work on it right now
on Apr 6, 2021
Veykril

Veykril commented on Apr 6, 2021

@Veykril
Member
JoshMcguigan

JoshMcguigan commented on Apr 6, 2021

@JoshMcguigan
Contributor

Thanks for the report!

I suspect a direct cause of this is that the expected_type field on CompletionContext doesn't consider the existence of a leading reference.

https://github.com/rust-analyzer/rust-analyzer/blob/e6a1c9ca60c19bf3b02b302e21d9f9fd9bd8a466/crates/ide_completion/src/context.rs#L310-L401

But an alternate solution, which might be better long term (?) is considering the leading reference as part of the thing being completed. In that case expected_type would stay as-is and we'd in this case just overwrite the existing &mut. The upside to this approach is if the user starts typing &con we could complete &mut context. The downside is if our ref completions were not very good, we could complete &mut con to perhaps context (deleting the &mut that the user has already entered).

In any event I'm glad to have this report as it gives an important additional use case to think about as I'm working on #8058.

kpreid

kpreid commented on Jul 5, 2022

@kpreid
Contributor

I keep hitting this problem when trying to complete struct fields (where the name I am looking for might be one I don't entirely remember), and it'd be really nice to have it fixed. As encouragement, here's a self-contained example:

fn foo(_: &mut i32) {}
struct S {
    some_field_with_a_long_name: i32,
}

fn main() {
    let s = S {
        some_field_with_a_long_name: 100,
    };
    foo(&mut s.so/* cursor here */);           
}

Put the cursor at the specified point and hit tab (in VS Code), and the extra &mut is inserted:

    foo(&mut &mut s.some_field_with_a_long_name);
self-assigned this
on Jul 7, 2022
added a commit that references this issue on Jul 27, 2022

Auto merge of #12887 - Veykril:compl-pref-fix, r=Veykril

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-completionautocompletionC-bugCategory: bugS-actionableSomeone could pick this issue up and work on it right now

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    Reference completions are a bit too aggressive · Issue #8357 · rust-lang/rust-analyzer