rust-lang / rust-analyzer

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

Does not detect errors in procedural macros #10031

Open liby opened 2 years ago

liby commented 2 years ago

Minimum reproduction repo

File Tree ``` . ├── Cargo.lock ├── Cargo.toml ├── hello_macro_derive │   ├── Cargo.toml │   └── src │   └── lib.rs ├── src │   ├── lib.rs │   └── main.rs └── target ├── CACHEDIR.TAG └── debug ```

https://user-images.githubusercontent.com/38807139/130913623-155b68d7-2716-4cb2-b93f-c4e5a952694f.mp4

lnicola commented 2 years ago

CC @jonas-schievink

This reports an error in the logs, but without diagnostics. Or was that intentional?

[ERROR rust_analyzer::reload] failed to switch build data: rust-analyzer failed to run build scripts:
error: could not compile `hello_macro_derive`
jonas-schievink commented 2 years ago

Flycheck diagnostics are independent of loading build script data, the issue might be that the repo does not use a workspace for the derive crate (just guessing at this point though)

liby commented 2 years ago

@jonas-schievink

the issue might be that the repo does not use a workspace for the derive crate (just guessing at this point though)

What do I have to do, please? Or is there anything I can do to help?

bjorn3 commented 2 years ago

Try adding [workspace] to the Cargo.toml in the root. That will make the whole project a single cargo workspace with a shared target dir and shared Cargo.lock. This should also make rust-analyzer recognize both the root crate and the proc-macro as part of the same project, thus likely showing diagnostics for the proc-macro.

liby commented 2 years ago

@bjorn3

Try adding [workspace] to the Cargo.toml in the root.

This does solve the issue. image

That will make the whole project a single cargo workspace with a shared target dir and shared Cargo.lock.

But when [workspace] is not added to the Cargo.toml in the root, they were already with a shared target dir and shared Cargo.lock (the file tree structure can reflect this), and the type inference and other features can be used (as seen in the video), but the cargo check is not effective, which makes me confused.

bjorn3 commented 2 years ago

Without [workspace] there would not be a shared target dir and Cargo.lock. If you cd to the proc-macro dir and then build, you will get an additional target dir and Cargo.lock inside the proc-macro dir. Without [workspace] cargo considers the proc-macro to be a dependency just like one from crates.io that just so happens to be inside a subdirectory. Cargo can't take the directory layout into account for workspaces as it doesn't know when to stop walking up. With workspaces it knows that it needs to walk up until a Cargo.toml containing [workspace]. To further eliminate false-positives it will error if a workspace has a crate in a subdirectory but doesn't have it as dependency or member inside the [workspace] section.

liby commented 2 years ago

@bjorn3

To further eliminate false-positives it will error if a workspace has a crate in a subdirectory but doesn't have it as dependency or member inside the [workspace] section.

Can you elaborate a bit here? I tried to list only proc-macro in [dependencies], not in the members block, and everything looks fine, with no problems. Maybe there's an obvious answer to the question I'm asking, but I'm sorry I'm still a little confused.

bjorn3 commented 2 years ago

With "or" I mean that you have to either add it as dependency or as member in the [workspace] section. You don't have to do both, doing one is fine.