rust-lang / rust-analyzer

A Rust compiler front-end for IDEs
https://rust-analyzer.github.io/
Apache License 2.0
14.25k stars 1.6k forks source link

flycheck: `rustc` diagnostics are not read properly #14217

Closed mibu138 closed 1 year ago

mibu138 commented 1 year ago

In the User Manual there is a section on setting up rust-analyzer for non-cargo based projects. I very much appreciate that this is something RA offers, and I've gotten it working more or less with the rust-project.json file in my project root, at least in terms of basic LSP functionality.

However, I can't seem to get the compile errors working, and I find these just too useful to not ask about them. I'm aware that normally this is done with cargo check, which is disabled by the presence of rust-project.json, but the documentation suggests that there is a way to replace cargo check with something else, as long as the output is a form of json. My thinking is to use a rustc based command in its place. Basically something like this:

rustc --error-format=json -o /dev/null

I've hacked up my LSP client (vim-lsc) to provide this command to rust-analyzer via the initializationOptions on start up. And I've verified through gdb that its getting to rust-analyzer and that rust-analyzer is indeed running this command when I save my file, but it always returns a "cargo check failed" repsonse. I've inverstigated this a bit and have found the following:

Here is what I think is a relevant snippet from RA's error logs:

[ERROR rust_analyzer::lsp_utils] cargo check failed:
Cargo watcher failed, the command produced no valid metadata (exit code: ExitStatus(unix_wait_status(256))):
{"message":"environment variable `REFLECTION_FILE` not defined","code":null,"level":"error","spans":[{"file_name":"examples/rust/compute-simple/main.rs","byte_start":150,"byte_end":173,"line_start":6,"line_end":6,"column_start":14,"column_end":37,"is_primary":true,"text":[{"text":"    include!(env!(\"REFLECTION_FILE\"));","highlight_start":14,"highlight_end":37}],"label":null,"suggested...............

The rest is just more output from rustc. Not sure what the flycheck error means.

So at this point I'm basically stuck. I don't know if the output of rustc is just not correct, or if there is something else I need to do. Any help on this would be greatly appreciated.

lnicola commented 1 year ago

This has been brought up in https://github.com/rust-lang/rust-analyzer/issues/13437, so you might want to follow the discussion there.

mibu138 commented 1 year ago

Thanks for the suggestion @lnicola . It looks like #13437 addresses the first issue I ran into, the one about the overrideCommand not being given the current file as an argument, but not the second part. That is, even when I give it an explicit file to compile and output rustc's message as json, it does not work. Is rustc's output not correct? I guess I'm asking what the structure of the json that r-a requires is. Or is there another reason this isn't working?

lnicola commented 1 year ago

Confirmed. The issue is around here.

cargo outputs the JSON to stdout with progress messages to stderr, while rustc outputs the JSON to stderr. We try there to parse either cargo or rustc messages, but we only look at stdout.

It works if you set:

{
    "rust-analyzer.check.overrideCommand": [
        "sh",
        "-c",
        "rustc --error-format=json src/main.rs 2>&1"
    ]
}
mibu138 commented 1 year ago

Ah, yes, redirecting output from rustc to stdout does appear to fix things. I can use that as a work around until there is a fix on r-a side. Thanks.