fix: Fix build scripts not being rebuilt in some occasions
Also makes proc-macro changed flag setting async, we don't wanna block `process_changes` on the database as that is on the main thread!
This commit also adds `tracing` to NotificationDispatcher/RequestDispatcher,
bumps `rust-analyzer-salsa` to 0.17.0-pre.6, `always-assert` to 0.2, and
removes the homegrown `hprof` implementation in favor of a vendored
tracing-span-tree.
Give a userful error when rustc cannot be found in explicit sysroot
Somehow r-a believed that my sysroot was something weird with no rustc. Probably a me issue, but it was impossible to diagnose since r-a just gave me a plain "No such file or directory". Adding this error makes it clear what happened and allows diagnosing the problem.
Somehow r-a believed that my sysroot was something weird with no rustc.
Probably a me issue, but it was impossible to diagnose since r-a just
gave me a plain "No such file or directory". Adding this error makes it
clear what happened and allows diagnosing the problem.
fix: Update metavariable expression implementation
Fixes https://github.com/rust-lang/rust-analyzer/issues/16154
This duplicates behavior of that before and after PR https://github.com/rust-lang/rust/pull/117050 based on the toolchain version. There are some 1.76 nightlies that are still broken (any before that PR basically) but fetching and storing the commit makes little sense to me (opposed to the toolchain version).
Make data reflect a case where dev deps are existent.
base-db::CrateGraph::extend now adds dev dependencies for a crate
in case of its upgrading from a CrateOrigin::Lib kind of a crate to a
CrateOrigin::Local one.
Partially fixes#15656 . When a crate graph is extended which is the case when new workspaces are added to the project
the rules for deduplication were too strict. One problem that arises from this is that in certain conditions
when we see the same crate having different `CrateOrigin`s the first form would be maintained. This approach however
results in some unwanted results such as making renaming forbidden as this has been recently only made available for
local crates. The given example in #15656 can still not be resolved with this PR as that involves taking inconsistencies
between dependencies into consideration. This will be addressed in a future PR.
Add dedicated field for `target_dir` in the configurations for Cargo
and Flycheck. Also change the directory to be a `PathBuf` as opposed to
a `String` to be more appropriate to the operating system.
project-model: when using `rust-project.json`, prefer the sysroot-defined rustc over discovery in `$PATH`
At the moment, rust-analyzer discovers `rustc` via the `$PATH` even if the `sysroot` field is defined in a `rust-project.json`. However, this does not work for users who do not have rustup installed, resulting in any `cfg`-based inference in rust-analzyer not working correctly. In my (decently naive!) opinion, it makes more sense to rely on the `sysroot` field in the `rust-project.json`.
One might ask "why not add `rustc` to the `$PATH`?" That is a reasonable question, but that doesn't work for my use case:
- The path to the sysroot in my employer's monorepo changes depending on which platform a user is on. For example, if they're on Linux, they'd want to use the sysroot defined at path `a`, whereas if they're on macOS, they'd want to use the sysroot at path `b` (I wrote the sysroot resolution functionality [here](765da4ca1e/integrations/rust-project/src/sysroot.rs (L39)), if you're curious).
- The location of the sysroot can (and does!) change, especially as people figure out how to make Rust run successfully on non-Linux platforms (e.g., iOS, Android, etc.) in a monorepo. Updating people's `$PATH` company-wide is hard while updating a config inside a CLI is pretty easy.
## Testing
I've created a `rust-project.json` using [rust-project](https://github.com/facebook/buck2/tree/main/integrations/rust-project) and was able to successfully load a project with and without the `sysroot`/`sysroot_src` fields—without those fields, rust-analyzer fell back to the `$PATH` based approach, as evidenced by `[DEBUG project_model::rustc_cfg] using rustc from env rustc="rustc"` showing up in the logs.
Deduplicate crates when extending crate graphs
This is quadratic in runtime per deduplication attempt, but I don't think that'll be a problem for the workload here. Don't be scared of the diff, the actual diff is +42 -22, the rest is tests and test data.
Fixes https://github.com/rust-lang/rust-analyzer/issues/14476
Detect sysroot dependencies using symlink copy
cc #7637
It is currently in a proof of concept stage, and it doesn't generates a copy. You need to provide your own sysroot copy in `/tmp/ra-sysroot-hack` in a way that `/tmp/ra-sysroot-hack/library/std/lib.rs` exists and `/tmp/ra-sysroot-hack/Cargo.toml` is [the one from this comment](https://github.com/rust-lang/rust-analyzer/issues/7637#issuecomment-1495008329). I will add the symlink code if we decide that this approach is not a dead end.
It seems to somehow work on my system. Go to definition into std dependencies works, type checking can look through fields if I make them public and `cfg_if` appears to work (I tested it by hovering both sides and seeing that the correct one is enabled). Though finding layout of `HashMap` didn't work.
Please try it and let me know if I should go forward in this direction or not.
fix: allow new, subsequent `rust-project.json`-based workspaces to get proc macro expansion
As detailed in https://github.com/rust-lang/rust-analyzer/issues/14417#issuecomment-1485336174, `rust-project.json` workspaces added after the initial `rust-project.json`-based workspace was already indexed by rust-analyzer would not receive procedural macro expansion despite `config.expand_proc_macros` returning true. To fix this issue:
1. I changed `reload.rs` to check which workspaces are newly added.
2. Spawned new procedural macro expansion servers based on the _new_ workspaces.
1. This is to prevent spawning duplicate procedural macro expansion servers for already existing workspaces. While the overall memory usage of duplicate procedural macro servers is minimal, this is more about the _principle_ of not leaking processes 😅.
3. Launched procedural macro expansion if any workspaces are `rust-project.json`-based _or_ `same_workspaces` is true. `same_workspaces` being true (and reachable) indicates that that build scripts have finished building (in Cargo-based projects), while the build scripts in `rust-project.json`-based projects have _already been built_ by the build system that produced the `rust-project.json`.
I couldn't really think of structuring this code in a better way without engaging with https://github.com/rust-lang/rust-analyzer/issues/7444.
This makes code more readale and concise,
moving all format arguments like `format!("{}", foo)`
into the more compact `format!("{foo}")` form.
The change was automatically created with, so there are far less change
of an accidental typo.
```
cargo clippy --fix -- -A clippy::all -W clippy::uninlined_format_args
```
Seems like these can be safely fixed. With one, I was particularly
surprised -- `Some(pats) => &**pats,` in body.rs?
```
cargo clippy --fix -- -A clippy::all -D clippy::explicit_auto_deref
```
Support multiple targets for checkOnSave (in conjunction with cargo 1.64.0+)
This PR adds support for the ability to pass multiple `--target` flags when using
`cargo` 1.64.0+.
## Questions
I needed to change the type of two configurations options, but I did not plurialize the names to
avoid too much churn, should I ?
## Zulip thread
https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Frust-analyzer/topic/Issue.2013282.20.28supporting.20multiple.20targets.20with.201.2E64.2B.29
## Example
To see it working, on a macOS machine:
```sh
$ cd /tmp
$ cargo new cargo-multiple-targets-support-ra-test
$ cd !$
$ mkdir .cargo
$ echo '
[build]
target = [
"aarch64-apple-darwin",
"x86_64-apple-darwin",
]
' > .cargo/config.toml
$ echo '
fn main() {
#[cfg(all(target_arch = "aarch64", target_os = "macos"))]
{
let a = std::fs::read_to_string("/tmp/test-read");
}
#[cfg(all(target_arch = "x86_64", target_os = "macos"))]
{
let a = std::fs::read_to_string("/tmp/test-read");
}
#[cfg(all(target_arch = "x86_64", target_os = "windows"))]
{
let a = std::fs::read_to_string("/tmp/test-read");
}
}
' > src/main.rs
# launch your favorite editor with the version of RA from this PR
#
# You should see warnings under the first two `let a = ...` but not the third
```
## Screen
![Two panes of a terminal emulator, on the left pane is the main.rs file described above, with warnings for the first two let a = declaration, on the right pane is a display of the .cargo/config.toml, an ls of the current files in the directory and a call to cargo build to show the same warnings as in the editor on the left pane](https://user-images.githubusercontent.com/7951708/192122707-7a00606a-e581-4534-b9d5-b81c92694e8e.png)
Helps with #13282
Implement invocation strategy config
Fixes https://github.com/rust-lang/rust-analyzer/issues/10793
This allows to change how we run build scripts (and `checkOnSave`), exposing two configs:
- `once`: run the specified command once in the project root (the working dir of the server)
- `per_workspace`: run the specified command per workspace in the corresponding workspace
This also applies to `checkOnSave` likewise, though `once_in_root` is useless there currently, due to https://github.com/rust-lang/cargo/issues/11007