-
Notifications
You must be signed in to change notification settings - Fork 255
Implement find implementations extension #181
Conversation
It would be good to communicate that you're working on this stuff before you get into it - I also have substantial changes to rls-analysis mostly implemented to support the save-analysis changes. To answer your questions:
|
@nrc If you already have the changes to rls-analysis that's good. Just use them and ignore my stuff. I do this more for fun and self-education anyway. But I try to communicate more, to avoid duplicating work. |
@jonasbb to be clear, I only have the rls-analysis parts implemented (and they are on master now) - I haven't done anything in VSCode or the RLS, so I think your work here will be very useful |
@nrc I changed it to use the upstream rls-analysis version. I dropped the find supertrait stuff for the moment. This can be added easily with some copy and paste. Lastly, I decided to filter out all paths starting with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this is looking good. The only bit that gives me pause is the checkout
filtering - more inline.
src/actions/mod.rs
Outdated
.into_iter() | ||
// FIXME: these are part of libstd and libcore but the path probably does not | ||
// exists and thus should be removed. Replace with correct path later. | ||
.filter(|x| x.file.starts_with(Path::new("/checkout/src/"))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious about this - why is it needed here and not for other queries? I think ideally any filtering like this should happen in rls-analysis, not here (and probably in a more principled way). I also think, but not sure, that this is probably incorrect, since this will cover all upstream crates, not just core/std, but it is only the std/core ones that do not exist?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this is an artifact how the save-analysis data is generated. I assume this is the path used in the buildbots.
In general this can only become a problem for the values ref_spans
and impls
in PerCreateAnalysis
, because here we map to a span. ref_spans
is only filled by the "refs":
array in the serialized json. globs
and def_id_for_span
map a span to something else. If they contain such a broken span this only leads to a failed lookup but not to wrong filenames being presented to the user.
In the local (target/rls
) analysis data I can only find references to the path /checkout/src/libcore/macros.rs
. They appear here only in the macro_ref
section, which is currently unused by rls-analysis, thus they could not have been a problem. No span in "refs"
contains such a path.
In the global ('rustlib/.../analysis') analysis data I see references to a lot of different files of the libraries. But none of those json files have any values in "refs"
, which is the only existing possibly problematic case.
This mean, neither the local nor global data could have contributed until this change with broken spans.
src/server.rs
Outdated
@@ -351,6 +354,12 @@ impl LsService { | |||
trace!("command(reformat range): {:?}", params); | |||
this.handler.reformat(id, params.text_document, &*this.output); | |||
} | |||
|
|||
// custom extensions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment is unnecessary
@nrc I addressed both comments by you. I just thought that a temporary solution for the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the change, I thought of something else we need to do - sorry I should have included this in the last review, but didn't think of it.
src/actions/mod.rs
Outdated
.unwrap_or(vec![]) | ||
.into_iter() | ||
.map(|x| ls_util::rls_to_location(&x)) | ||
.collect(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we spawn a thread with timeout to do this please? We do that for the other queries (e.g., find all refs) and I think we should do it here too).
It would also be great to add a test for this. |
Hey @jonasbb, are you still working on the issue by any chance? |
I updated the implementation and implemented a test case for it. This generates two new warnings for unused items, once in src/actions/lsp_extensions.rs:16 and in src/server.rs:17, but I am not sure if I should just put a couple of allow annotations on them. The import is needed for the code generated by the macro, but somehow rust still annotates it as unused_import. The updated client changes are in https://github.com/jonasbb/rls_vscode/tree/find-impls |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Could we put this behind the unstable features config flag please? (At least to start with)
src/server.rs
Outdated
@@ -247,6 +247,7 @@ messages! { | |||
"textDocument/rename" => Rename(RenameParams); | |||
"textDocument/formatting" => Formatting(DocumentFormattingParams); | |||
"textDocument/rangeFormatting" => RangeFormatting(DocumentRangeFormattingParams); | |||
"rustDocument/implementations" => FindImpls(TextDocumentPositionParams); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use the const here?
src/actions/mod.rs
Outdated
let analysis = self.analysis.clone(); | ||
|
||
let handle = thread::spawn(move || { | ||
// FIXME send failure |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you expand this comment please
src/actions/mod.rs
Outdated
} | ||
Err(_) => { | ||
out.failure(id, "Find Implementations failed to complete successfully"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style nit: I'd get rid of the {}
here
That is kind of disturbing - I guess this happens because the identifier is put together with concat_idents - this is presumably a bug in the Rust compiler. Could you add the allow annotations please? |
Lets give this one more try. |
The new test seems to be failing, hard to tell why. |
List all implementation block for traits, structs, and enums. Fails for traits which are implemented using derive Listed under wishlist #142 Requires the find-impls branch of https://github.com/jonasbb/rls_vscode
This test contains code for testing implementations of |
I don't really understand the test issue - what is rust-analysis and why is it needed for the test? What do type ids have to do with it? The URL in the comment links to a passing Travis test, so I can't see any error messages. The Cargo.toml doesn't mention rust-analysis, so I don't know why Cargo needs to install it. Could you just test for the literal |
@nrc sorry for being so brief. It was late last night. I wrote tests to find implementation for three different spans in the test. The last span is The url in the comment is passing because for debugging I installed the rust-analysis component once on Travis. If I do this the test passes. Now the code tests Sub and Super. The Eq is commented out with a reasoning why it does not work on Travis. Derives where never tested in the first place. |
Ah, OK, I understand thanks! And thanks for working on this for so long! |
I'm just glad that finally everything is in order :) |
@jonasbb I tried to use the Find Implementations, but got this error: |
The error message means, that rls-analysis is not able to get a typeid from a span. This either means the span (selected characters) does not match any known type or somehow the analysis data is missing a Def definition for this type. It would help if you could mention what was under your cursor when invoking the command. I don't know if a workspace has any influence on the analysis data. |
@jonasbb struct MyStruct;
trait MyTrait {}
impl MyTrait for MyStruct {} I had crashes for Meta:
|
@Xanewok For a simple library project (only a lib.rs with your content above) it works for me. I try to look at a workspace later. Although I have never used them before, so it might take a while. |
I tried doing the same in bare lib or bare bin project, but to no avail. I'll try fixing my setup. |
I tried using the recent addition to the save-analysis data to tackle two items from the wishlist.
Find all implementations of trait.
Listed under wishlist tracking issue: wishlist #142
Fails for traits which are implemented using derive
Find supertrait of trait
Listed under wishlist tracking issue: wishlist #142
Only proof of concept, not yet transitive.
To Check: Which span makes more sense. The span of the supertrait (as
currently) or the span of where the subtrait defines the dependency?
Requires the find-impls branch of https://github.com/jonasbb/rls_vscode
Also requires the find-impls branch of rls-analysis.
I have a few specific questions which I am not sure how to tackle them:
PartialEq
only produces spans with a file path like/checkout/src/libstd/
.lower_span
inrls_analysis
is not able to convert them correctly. Should this be fixed in rustc orrls_analysis
and how? The spans do not have any information in them to indicate the invalid file paths.