Rust-analyzer: "add missing impl members" intetion

Created on 23 Feb 2019  路  4Comments  路  Source: rust-analyzer/rust-analyzer

For code like

trait Foo {
    fn foo(&self);
}

struct S;

impl Foo for S {
    // cursor here
}

suggest adding fn foo method.

This belongs to ra_assists crate. Long-term, this should become part of the hir, once we implement item checking. At this time however, I don't think we can avoid false positives, so let's make this an assist.

The asssit should find an impl at the cursor and resolve the corresponding trait. See this code for how this should be done.

Then, it should compare trait's and impl's set of methods, consts, etc, and construct an edit to add missing ones.

E-has-instructions E-medium fun

Most helpful comment

In case someone wants to learn from browsing the issues and to keep things centralized, I'll post the mentoring notes that @matklad kindly offered:

I think atm this should be a syntax-based assist
you check if the cursor is inside an impl (there's find_node method on AssistCtx)
then you get the path to the trait, and resolve that path
resolving the path will give you a hir::Trait back. You need to convert it to ast::Trait, and then compare a set of items on ast::Trait and ast::Impl

I'm starting the work on it right now.

All 4 comments

How can i get all the methods from a trait? Seems there doesn't exist a method to get the function defs from the trait.

Another thing to keep in mind is to manage default methods. I think they should be treated as already implemented but there should be an option to override them.
One option is to generate multiple assists dynamically, one assist for each overridable method.
[That's one of the use cases I had in mind when I refactored the code to support multiple assists some time ago]

Another option would be to implement some kind of custom completion directive, so one write:

impl X for Foo {
    :override.<|> 
}

The autocompletion engine recognise :override so if we are in a trait impl block it give the list of default overridable methods as completion options. Selecting one of them autocompletes to the method boilerplate.

This completion directive approach can be reused for other purposes, but the multiple assist approach is more discoverable.

I think it might make sense to have "Add Missing Impl Members" add only the methods which require implementation, then having a separate "override" code assist, which could contain "Override all members" and then individually generated overrides for each member in the trait.

In case someone wants to learn from browsing the issues and to keep things centralized, I'll post the mentoring notes that @matklad kindly offered:

I think atm this should be a syntax-based assist
you check if the cursor is inside an impl (there's find_node method on AssistCtx)
then you get the path to the trait, and resolve that path
resolving the path will give you a hir::Trait back. You need to convert it to ast::Trait, and then compare a set of items on ast::Trait and ast::Impl

I'm starting the work on it right now.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

RazrFalcon picture RazrFalcon  路  4Comments

AlseinX picture AlseinX  路  3Comments

cole-miller picture cole-miller  路  3Comments

GopherJ picture GopherJ  路  3Comments

matklad picture matklad  路  4Comments