The file paths returned by rls-analysis are relative to the current working directory, while racer returns absolute paths.
Take this simple code snippet for instance, assuming it'd be located at /Users/username/project:
use std::io;
fn main() {
let _ = io::stdin();
}
If you try to go to the definition of io (the one inside the main function) it works, because rls falls back to racer here, which returns the full absolute path to the Rust source file:
INFO:rls::actions: goto_def - falling back to Racer
DEBUG:rls::server: response: "Content-Length: 232\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":40,\"result\":[{\"uri\":\"file:///Users/username/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/src/libstd/net/mod.rs\",\"range\":{\"start\":{\"line\":0,\"character\":1},\"end\":{\"line\":0,\"character\":1}}}]}"
Formatted:
{
"jsonrpc": "2.0",
"id": 40,
"result": [
{
"uri": "file:///Users/username/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/src/libstd/net/mod.rs",
"range": {
"start": {
"line": 0,
"character": 1
},
"end": {
"line": 0,
"character": 1
}
}
}
]
}
If however you try to go to the definition of stdin it won't work:
DEBUG:rls::server: response: "Content-Length: 187\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":76,\"result\":[{\"uri\":\"file:///Users/username/project/src/libstd/io/stdio.rs\",\"range\":{\"start\":{\"line\":204,\"character\":7},\"end\":{\"line\":204,\"character\":12}}}]}"
Formatted:
{
"jsonrpc": "2.0",
"id": 76,
"result": [
{
"uri": "file:///Users/username/project/src/libstd/io/stdio.rs",
"range": {
"start": {
"line": 204,
"character": 7
},
"end": {
"line": 204,
"character": 12
}
}
}
]
}
See how the path is now relative to my project root, where VSCode as well as rls were spawned in?
I tried understanding and possibly fixing rls-analysis (where the bug should be at I believe), however I was unable to find the cause in a reasonable time frame.
It'd be nice if someone could fix this issue or help me fix it myself. 馃檪
Goto-definition for stdlib symbols has been broken in VSCode (editor-rs/vscode-rust) for weeks due to this, unless I'm doing something stupid and this is coincidence/unrelated. Ping?
Is this broken with the test plugin also (https://github.com/jonathandturner/rls_vscode)?
Would be great to try against the rustup nightly rls, now that it's available.
I tried rls via rustup – no difference in behavior. I've also tried all combinations of setting (or not) RUST_SRC_PATH and vscode-rust's rust.rustLangSrcPath setting to no avail.
I haven't tried rls_vscode, I'll give it a shot this evening.
Apologies for the delay. I tried with the test plugin, exact same outcome: attempting to go to the definition of stdlib components fails, with an error message indicating that it's looking for the source file relative to rather than in ${workspaceRoot}RUST_SRC_PATH.
I'm testing with Rust nightly 2017-04-20 and rls from rustup, and latest VSCode Insiders nightly. Please let me know what other information I can provide.
EDIT: I just realized a mistake: it's looking for stdlib source files relative to VSCode's installation directory, not relative to ${workspaceRoot}.
The tricky thing here is that goto_def works through two different paths in RLS. The first is that it uses Racer, the second uses the compiler. IIRC it's time dependent on which one you're going to get first.
In the long term, everything will get serviced by the compiler. In the short term, there may be issues like this.
Okay, that said... Going to definition on something in stdlib I don't believe is currently supported. We should show you the type info and the docs, but we don't open up the source to the stdlib itself and drop you in it. This is on purpose, as most users won't want to swim through the stdlib source, but rather will want to understand how to use it.
Are you seeing this behaviour with definitions outside of the stdlib?
Are you seeing this behaviour with definitions outside of the stdlib?
No, stdlib only; other external crates work great.
Going to definition on something in stdlib I don't believe is currently supported. We should show you the type info and the docs, but we don't open up the source to the stdlib itself and drop you in it.
Oh... Well, it reliably did just that until ~1 month ago, so I assumed that was the expected behavior. I find it quite useful, personally; and anything would be an improvement on getting a bogus error for not finding the source file. Consider it a feature request I suppose? :-]
I honestly don't see the point in forbidding to go into the standard library on purpose. If someone doesn't want to go into it, he can simply not do that. Not allowing to do that, however, creates a problem for all those who want to. And showing the documentation and the type information should be working for everything anyway, including the standard library.
I honestly don't see the point in forbidding to go into the standard library on purpose.
Users may not have the stdlib source code installed on their system. Ideally we would jump to source if it is available (I guess we have to know where the source code is on the system some how, but I assume the installation path is predictable? Or we can query rustup or something?). If the user does not have the stdlib source installed, then we should not offer goto def for it (we have URLs for the source and doc online, so we can open a web page for it, but only in the browser, not inside VSCode, afaik).
Users may not have the stdlib source code installed on their system.
Step 3 for installing RLS involves rustup component add rust-src --toolchain nightly, so this should not be a concern.
That step is only necessary for making Racer work, it is not mandatory
Users may not have the stdlib source code installed on their system.
There could be a prompt to install it or go to the standard library documentation. Besides, as dodheim says, right now RLS requires Racer, which means that the source should be present anyway. I don't think that will change any time soon.
This is on purpose, as most users won't want to swim through the stdlib source, but rather will want to understand how to use it.
Then don't return a goto def at all, as per @nrc's recommendation. Opening the matching definition on https://doc.rust-lang.org/ or https://docs.rs/ respectively is probably a very good idea and it might make sense to make it the default even.
But in the end of the day we are all programmers here and the idea that the majority wouldn't want to be at least able to read the source code of what gets actually compiled is laughable at best. In no other engineering field that'd be something you'd want to hear. "Hey I'm building elevators according to what I read on wikipedia. It's totally safe to use - Trust me guys!!"
Nah come on... Make it a option at least. And please tell me/us how to fix it, by making it return absolute paths, because the current state makes code editing really annoying right now.
That step is only necessary for making Racer work, it is not mandatory
All that aside, right now if I goto-def on a stdlib _module_ it goes to the source just fine; it's only if I goto-def on a stdlib function or type that it errors out. This inconsistency is simply not justifiable.
I have the docs; I don't want a link to the docs, I want to see the source. Why am I using the disk space just to have the tooling ignore it?
will there be a fix for this issue?
@hicder there should be at some point, yes
Just to be clear: disallowing goto-def on the stdlib is not the fix being asked for here...
My current solution to this is to create a symlink to the /checkout/src directory. As the RLS debug log indicates, it knows already where the source is anyway:
DEBUG: runInRlsMode: env={"RUST_SRC_PATH":"/home/fungos/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src"}
So not sure why it can't remap the /checkout/src to this one, so I've done it via a symlink.
@fungos The main developers of RLS actually don't want to support goto_def for types in the std lib. Therefore, the error is that RLS even send any span with a /checkout path in it. That's why there is no remapping.
There was an error in the files distributed with rustup which didn't mark the std lib files as being the std lib, which might explain why you did see this error.
I understand that, but I feel this may not be the expected behavior for a "Go to definition" feature. Not sure how this works with other languages like Python or Ruby, but as for Visual Studio/QtCreator and C, C++, C#, VSCode with TypeScript, Eclipse and Intellij with Java, go to definition does what it means even for std things.
I get you may want threat it differently for std, but at least it should be configurable or have sensible fallback (ie: couldn't show/find docs, try opening the source).
But at the end of the day, it still not "going to the definition". A hover should display the signature and doc summary. F1 should open the doc in a browser or preferably, split the window and open the doc inside the IDE (ie. QtCreator).
@jonasbb i really hope they will in the future at least make that configurable (if not default).
When i ask my IDE to go to the definition of a method or function, then i want to see the source code (if at all available).
Showing the documentation is another very useful functionality for any code not only the standard library. But it is a competely different functionality and should not be mixed up imho.
I wonder whether this could be done in a more intelligent way. Apparently I would like to see documents of std library when I "ctrl + hover" a function and step into std source when "step into" is used in an IDE.
What I don't like is that currently if I create the /checkout/src symbolic link, it will take me deep into the std source at the end of any program even if only "step over" is used and end up with some confusing error messages.
Jumping to stdlib source code is absolutely critical functionality. Taking it away would make rls unusable for me. What could be better reference for idiomatic rust if not stdlib?
If rust-src is not available, RLS should return an error message saying that the source is not found and provide the exact command to install the component through rustup.
If rust-src is available, RLS should go in the source code of the standard library. Doing anything else is inconsistent and from reading the comments, not anything that anyone wants.
Yeah, the plan is that we should jump into the source from rust-src. Pretty much having the RLS ensures that the user also has rust-src, so I think that not having it will not be an issue.
(This was not the case earlier, which is why I was a bit luke warm about jumping into the source, but now I think it is the best road forward).
What's the current status of this issue, I still can't jump to the correct file using a newly installed rls extension in vscode.
goto definition for std.
mark.
2018 already. It does not only break goto defination, but also interfere debugger for VS Code
I write a tool to fix this issue temporary, change the relative path of std analysis files to the absolute path. https://github.com/monkeycz/rustlib-analysis-fix
What's the status on this? I recently started rust and this issue turns quickly familiarizing myself with the standrad APIs more difficult than it should be.
@mandreyel I previously used a workaround of creating a symlink from /checkout to the rust-src path, but I don't think it's working any more. Last time I tried, it was looking for rust-src under my project's path. This was easy to see in VS Code because it displays the invalid path. Unfortunately, sometimes it simply does nothing, instead of reporting an error.
So it doesn't look like anyone is working on fixing this, but you might find some way around it.
@lnicola Symlinking /checkout to the rust source seems to have mostly solved it for me with Vim and LanguageClient-neovim, though sometimes it still can't find things (which is likely a limitation in rls).
It is somewhat baffling that such an important usability issue has remained unsolved for so long. I really hope it gets fixed (and by fixed I don't mean completely removed, as suggested in earlier responses) sooner than later--the above workaround is really not a pretty one.
In fact, I'd be willing to help, once my familiarity with rust is up to speed.
I believe the issue is that the analysis files shipped for std can't point to the source location on disk. And there is no way to mark them with "these paths should be relative to the install directory". Looking at the references commits, it seems that somebody tried to implement this and gave up.
Thank you, @jonasbb & @nrc (et. al.?), for fixing this bug. 馃槉馃帀馃帀馃帀
@lhecker Is it fixed? I got here because I had this issue with Virtual studio code.
@jonathan-s fixed on nightly at least, might not be on stable yet.
@jonathan-s same here, but i found that setting "rust.goto_def_racer_fallback": true helps a bit.
racer can at least jump to struct definitions, but seems like it can't jump to definitions of methods on traits.
Most helpful comment
Yeah, the plan is that we should jump into the source from rust-src. Pretty much having the RLS ensures that the user also has rust-src, so I think that not having it will not be an issue.
(This was not the case earlier, which is why I was a bit luke warm about jumping into the source, but now I think it is the best road forward).