Replicated in https://github.com/eclipse/corrosion:
Additional information:
Cargo.toml to .cargo, doesn't fix thispkill rls restores the IDE to an unstable state which constantly re-triggers an RLS build[t=1554109173638] org.eclipse.corrosion.rls to LSP4E:
{"jsonrpc":"2.0","method":"window/progress","params":{"id":"progress_0","title":"Indexing"}}
[t=1554109173638] LSP4E to org.eclipse.corrosion.rls:
{"jsonrpc":"2.0","id":"2","method":"textDocument/codeLens","params":{"textDocument":{"uri":"file:[...]/.cargo/[...]"}}
}
[t=1554109173638] org.eclipse.corrosion.rls to LSP4E:
{"jsonrpc":"2.0","method":"window/showMessage","params":{"message":"could not find `Cargo.toml` in `/` or any parent directory","type":1}}
[t=1554109173638] LSP4E to org.eclipse.corrosion.rls:
Content-Length: 3864
rls can't handle child projects without a workspace manifest in the current/parent dir, see #1202.
When rls is opened somewhere that cargo check will work it can actually handle out-of-project files like the std library and dependencies, but client's need to handle the messaging of these properly.
The library source file which causes the issue is a dependency of the project, so it falls into the "in-project" case. This happens whether the project contains a workspace (having its own appropriate Cargo.toml manifest), or a single binary.
The LSP4E maintainers are generally religious on following the LSP specifications. If there is a documented "correct" way of handling this case, I think Corrosion should follow it. Do you have a pointer to the docs?
Well rls works with out-of-project files the same way as in-project files. Send it the lsp messages and it will respond. To rls, similarly to cargo check, the current dir is just where to look for the manifest.
So just for context; rls does work with dependencies if you send it the messages. In practice though it's tricky.
If there is a documented "correct" way of handling this case
There is no documented way of running rls in the ~/.cargo dir because it won't work.
To clarify, we are not running RLS in the ~/.cargo dir. We only need RLS to look for dependency sources in the ~/.cargo dir.
So just for context; rls does work with dependencies if you send it the messages
I'm not following. Do you need special messages for the dependencies?
This error happens when rls is run from somewhere it doesn't like. Just like cargo check. This is because rls is cargo check ... with added memory usage.
~/.cargo $ cargo check
error: could not find `Cargo.toml` in `/home/alex/.cargo` or any parent directory
Hmm looking at that now it's suggesting that the titular error is rls is being run from root /. So that's something to look at clientside as rls will just run wherever it's run. Like cargo check.
``
~ $ cd /
/聽$聽cargo check
error: could not findCargo.tomlin/` or any parent directory
$ file /proc/$(pgrep rls)/cwd
/proc/15427/cwd: symbolic link to /home/norru
@mickaelistria, is it right? We run (or should run) only 1 instance of RLS for the entire IDE, and that instance should manage all projects in the workspace (RLS seems to be forking a lot but it all stems from the same root process)
@alexheretic Is this incorrect? Should we be running an instance of RLS for each Rust project? Because I think this would be a BIG architectural change for Corrosion. Also not sure it is the way LSP should be used.
Besides it, RLS seems to work most of the time, so I guess there is something in RLS that allows it to choose the correct Cargo.toml.
Having to start RLS from a specific directory which is supposed to contain a Cargo.toml file seems to be a real spanner in the works as it would bind the RLS process to a specific process.
Yes... rls only works for one project. Or more accurately it works where cargo check works and nowhere else.
So it will work for lots of crates inside a single workspace, but I'm including that in this comment's definition of "one project". If you want to edit a couple of distinct projects you'll need 2 rls processes running.
But this is not new behaviour, this has always been true as far as I can remember.
Yes... rls only works for one project
Oh dear, it is so by design?
So it may explain the instability. @mickaelistria Did you know about this? Is it the reason why RLS gets re-initialized every time I switch from a project to another?
If RLS by design only works for one project and LSP4E by design only has one instance of RLS, then I am afraid something has to give.
It is absolutely unacceptable for me NOT to have multiple Rust projects in a Workspace.
Really not keen to switch to VSC though.
This is what happens when I switch files across projects:
{"jsonrpc":"2.0","id":"1","method":"initialize","params":{"processId":20615,"rootPath":"/home/norru/Projects/ivt/toolkit/code/rust/ivt_util/","rootUri":"file:///[PROJECT_ROOT]/","initializationOptions":{"settings":{"rust":{"clippy_preference":"on"}}},"capabilities":{"workspace":{"applyEdit":true,"workspaceEdit":{"documentChanges":true,"resourceOperations":["create","delete","rename"],"failureHandling":"undo"},"symbol":{},"executeCommand":{"dynamicRegistration":true},"workspaceFolders":true}
So it's an initialize with a new rootPath to match the project.
Right that means rls has been killed and a new process has been started up, the _initialize_ request can only be sent once as the first message.
So that makes sense, starting an rls process whenever you switch project. Maybe not the most performant, but it should work. This brings us back to the .cargo issue. Using this dir as a rls root won't work.
If RLS by design only works for one project and LSP4E by design only has one instance of RLS, then I am afraid something has to give.
Right that means rls has been killed
Actually, just checking - I have multiple RLS children from Eclipse so this not quite correct. So it was implemented in LSP4E after all.
$ pstree
| | | | |-sh---eclipse-+-rls---29*[{rls}]
| | | | | |-rls---26*[{rls}]
| | | | | |-rls---2*[{rls}]
| | | | | `-116*[{eclipse}]
@alexheretic question: if we are specifying the rootPath in the initializer, why does RLS need to start from a Cargo.toml root?
It shoudn't _need_ to, when I implemented ide-rust it wouldn't work unless it was started in the right dir. That may be fixed now. But rootPath or cwd are essentially the same concept in that it has to run in some directory.
But rootPath or cwd are essentially the same concep
They're not. In one case we're starting the process from a directory, in the second one we're starting the process from any place and then telling it what its working directory is.
rootPath is always specified in Corrosion so there is no need to start RLS from where Cargo.toml is.
I am not an expert on the LSP4E internals (hello @mickaelistria!) but, in terms of RLS, I think that when LSP4E creates the process it doesn't have a clue on where Cargo.toml is, and it's only afterwards, when it kinda hands control over to the "project" it belongs to, that it gets told where to go.
We should not be constrained to start RLS from an arbitrary directory (I guess this is just my $HOME) because the rootPath does the job.
Besides it, creating a dummy /Cargo.toml makes the error disappear. This is a nasty workaround though.
I mean with rootPath working properly rls will start cargo/rustc in that folder. So it is essentially the same concept. So what rootPath is it using for the .cargo deps?
So what rootPath is it using for the .cargo deps?
"rootUri":"file:///$HOME/.cargo/
But this is only because I've got a project called .cargo in the Eclipse workspace.
If I remove that project, the "rootUri" should be the same as the dependee.
Ok, another one. initialize is always called with the same processId. No RLS gets killed I think. It may be that it just gets initialized multiple times.
I wonder what the multiple rls instances shown in pstree could be. Perhaps they're just OS threads.
"initialize","params":{"processId":20615,
I think there is something fishy in the integration code, but also something fishy in the Cargo.toml loading in RLS (ie RLS shouldn't be checking for Cargo.toml in cwd by default, or at least shouldn't barf)
That's the parent process id, not RLS pid. RLS cannot be initialized multiple times. I'm done with this.
That's the parent process id
Ok, that makes sense.
I'm done with this.
I hope you reconsider. I actually appreciate your help in understanding the integration process. I think this discussion will be hugely helpful to address the problem in LSP4E.
Likely a Corrosion integration - I think I'm mistaken in thinking Corrosion only runs one instance of RLS. The only question here is why does RLS require to start from the root of a Cargo project (after all there is rootPath in initialize).
Will reopen if this assumption is incorrect.
Same problem while running code in Vs Code, there is a setting though for RUST, "Rust-Client: Enable Multi Project Setup". Which says in the description that it will disable the error for the Cargo.toml file requirement.
@iaxat Interesting, do you know if it's a VSC-specific client setting, or it's something that can be configured via "initialize"?
@iaxat Interesting, do you know if it's a VSC-specific client setting, or it's something that can be configured via "initialize"?
It is the VSCode's Rust extension feature, and I used it and there is no problem anymore. You should try it.
@iaxat Interesting, do you know if it's a VSC-specific client setting, or it's something that can be configured via "initialize"?
It is the VSCode's Rust extension feature, and I used it and there is no problem anymore. You should try it.
I tried this but still VS will prompt "could not find Cargo.toml in x:\xxx\xxx\xxxor any parent directory" at launch, not sure y.
Most helpful comment
I tried this but still VS will prompt "could not find
Cargo.tomlinx:\xxx\xxx\xxxor any parent directory" at launch, not sure y.