Add a new configuration settings to set env vars when running cargo, rustc, etc. commands: cargo.extraEnv and checkOnSave.extraEnv
It can be extremely useful to be able to set environment variables when rust-analyzer is running various cargo or rustc commands (such as `cargo check`, `cargo --print cfg` or `cargo metadata`): users may want to set custom `RUSTFLAGS`, change `PATH` to use a custom toolchain or set a different `CARGO_HOME`.
There is the existing `server.extraEnv` setting that allows env vars to be set when the rust-analyzer server is launched, but using this as the recommended mechanism to also configure cargo/rust has some drawbacks:
- It convolutes configuring the rust-analyzer server with configuring cargo/rustc (one may want to change the `PATH` for cargo/rustc without affecting the rust-analyzer server).
- The name `server.extraEnv` doesn't indicate that cargo/rustc will be affected but renaming it to `cargo.extraEnv` doesn't indicate that the rust-analyzer server would be affected.
- To make the setting useful, it needs to be dynamically reloaded without requiring that the entire extension is reloaded. It might be possible to do this, but it would require the client communicating to the server what the overwritten env vars were at first launch, which isn't easy to do.
This change adds two new configuration settings: `cargo.extraEnv` and `checkOnSave.extraEnv` that can be used to change the environment for the rust-analyzer server after launch (thus affecting any process that rust-analyzer invokes) and the `cargo check` command respectively. `cargo.extraEnv` supports dynamic changes by keeping track of the pre-change values of environment variables, thus it can undo changes made previously before applying the new configuration (and then requesting a workspace reload).
Fix add reference action on macros.
Before we were using the range of the corresponding expression node in the macro expanded file, which is obviously incorrect as we are setting the text in the original source.
For some reason, the test I added is failing and I haven't found a way to fix it. Does anyone know why `check_fix` wouldn't work with macros? Getting this error:
```text
thread 'handlers::type_mismatch::tests::test_add_reference_to_macro_call' panicked at 'no diagnostics', crates/ide-diagnostics/src/handlers/type_mismatch.rs:317:9
```
closes#13219
Use memmem when searching for usages in ide-db
We already have this dependency, so there is no reason not to use it as it is generally faster than std in our use case.
Allow configuration of annotation location.
I've added the ability to configure where lens annotations render relevant to the item they describe. Previously, these would render directly above the line the item is declared on. Now, there is the ability to render these annotations above the entire item (including doc comments, and attributes).
The names of the config options are up for debate, I did what seemed best to me but if anyone has better ideas let me know.
This is my first contribution so if I've missed anything please let me know.
Here's a preview of what the new option looks like:
<img width="577" alt="Screen Shot 2022-09-11 at 10 39 51 PM" src="https://user-images.githubusercontent.com/33100798/189570298-b4fcbf9c-ee49-4b79-aae6-1037ae4f26af.png">
closes https://github.com/rust-lang/rust-analyzer/issues/13218
fixup: remove unnecessary `Option`
Fixup for #13223, two things:
- `normalize_projection_query()` (and consequently `HirDatabase::normalize_projection()`) never returns `None` (well, it used to when I first wrote it...), so just return `Ty` instead of `Option<Ty>`
- When chalk cannot normalize projection uniquely, `normalize_trait_assoc_type()` used to return `None` before #13223, but not anymore because of the first point. I restored the behavior so its callers work as before.
Restructure `find_path` into a separate functions for modules and non-module items
Follow up to https://github.com/rust-lang/rust-analyzer/pull/13212
Also renames `prefer_core` imports config to `prefer_no_std` and changes the behavior of no_std path searching by preferring `core` paths `over` alloc
This PR turned into a slight rewrite, so it unfortunately does a few more things that I initially planned to (including a bug fix for enum variant paths)
New assist: move_format_string_arg
The name might need some improving.
```rust
fn main() {
print!("{x + 1}");
}
```
to
```rust
fn main() {
print!("{}"$0, x + 1);
}
```
fixes#13180
ref to #5988 for similar work
* extracted `format_like`'s parser to it's own module in `ide-db`
* reworked the parser's API to be more direct
* added assist to extract expressions in format args
fix: handle lifetime variables in projection normalization
Fixes#12674
The problem is that we've been skipping the binders of normalized projections assuming they should be empty, but the assumption is unfortunately wrong. We may get back lifetime variables and should handle them before returning them as normalized projections. For those who are curious why we get those even though we treat all lifetimes as 'static, [this comment in chalk](d875af0ff1/chalk-solve/src/infer/unify.rs (L888-L908)) may be interesting.
I thought using `InferenceTable` would be cleaner than the other ways as it already has the methods for canonicalization, normalizing projection, and resolving variables, so moved goal building and trait solving logic to a new `HirDatabase` query. I made it transparent query as the query itself doesn't do much work but the eventual call to `HirDatabase::trait_solve_query()` does.
fix: handle trait methods as inherent methods for trait-related types
Fixes#10677
When resolving methods for trait object types and placeholder types that are bounded by traits, we need to count the methods of the trait and its super traits as inherent methods. This matters because these trait methods have higher priority than the other traits' methods.
Relevant code in rustc: [`assemble_inherent_candidates_from_object()`](0631ea5d73/compiler/rustc_typeck/src/check/method/probe.rs (L783-L792)) for trait object types, [`assemble_inherent_candidates_from_param()`](0631ea5d73/compiler/rustc_typeck/src/check/method/probe.rs (L838-L847)) for placeholder types. Notice the second arg of `push_candidate()` is `is_inherent`.
Previously, annotations would only appear above the name of an item (function signature, struct declaration, etc).
Now, rust-analyzer can be configured to show annotations either above the name or above the whole item (including doc comments and attributes).
The name might need some improving.
extract format_like's parser to it's own module in ide-db
reworked the parser's API to be more direct
added assist to extract expressions in format args
fix: sort all bounds on trait object types
Fixes#13181#12793 allowed different ordering of trait bounds in trait object types but failed to account for the ordering of projection bounds. I opted for sorting all the bounds at once rather than splitting them into `SmallVec`s so it's easier to do the same thing for other bounds when we have them.
fix: Insert whitespaces into static & const bodies if they are expanded from macro on hover
Partially fixes#13143.
To resolve the other part we need to expand macros in unevaluated static & const bodies, and I'm not sure we want to. If for example it includes a call to `assert!()`, expanding it will lead to worse hover.
It seems that we've accidentally deleted the tests here couple of years
ago, and then fairly recently made a typo during refactor as well.
Reinstall tests, with coverage marks this time :-)
A Resolver *always* has a module scope at the end of its scope stack,
instead of encoding this as an invariant we can just lift this scope
out into a field, allowing us to skip going through the scope vec
indirection entirely.
feat: Implement `feature(exhaustive_patterns)` from unstable Rust
Closes#12753
Recognize Rust's unstable `#![feature(exhaustive_patterns)]` (RFC 1872). Allow omitting visibly uninhabited variants from `match` expressions when the feature is on.
This adjusts match checking to the current implementation of the postponed RFC 1872 in rustc.
fix: Parse TypePathFn with preceding `::`
e.g. `impl Fn::() -> ()`.
Fixes#13157. This was the problem, not that the path was not at the end.
I could unify the parsing of `::` of TypePathFn with that of generic arg list, but some code relies on the `::` of generic arg list to be inside it.
fix: Lower float literals with underscores
Fixes#13155 (the problem was the `PI` is defined with `_f64` suffix). `PI` is still truncated, though, because `f64` cannot represent the value with full precision.
Highlight namerefs by syntax until proc-macros have been loaded
Usually when loading up a project, once loading is done we start answering highlight requests while proc-macros haven't always been loaded yet, so we start out with showing a lot of unresolved name-refs. After this PR, we'll use syntax based highlighting for those unresolved namerefs until the proc-macros have been loaded.
Remove hir::Expr::MacroStmts
This hir expression isn't needed and only existed as it was simpler to
deal with at first as it gave us a direct mapping for the ast version of
the same construct. This PR removes it, properly handling the statements
that are introduced by macro call expressions.
This hir expression isn't needed and only existed as it was simpler to
deal with at first as it gave us a direct mapping for the ast version of
the same construct. This PR removes it, properly handling the statements
that are introduced by macro call expressions.
feature: Assist to turn match into matches! invocation
Resolves#12510
This PR adds an assist, which convert 2-arm match that evaluates to a boolean into the equivalent matches! invocation.
fix: Only move comments when extracting a struct from an enum variant
Motivating example:
```rs
#[derive(Debug, thiserror::Error)]
enum Error {
/// Some explanation for this error
#[error("message")]
$0Woops {
code: u32
}
}
```
now becomes
```rs
/// Some explanation for this error
#[derive(Debug, thiserror::Error)]
struct Woops{
code: u32
}
#[derive(Debug, thiserror::Error)]
enum Error {
#[error("message")]
Woops(Woops)
}
```
(the `thiserror::Error` derive being copied and the struct formatting aren't ideal, though those are issues for another day)
fix: sort and deduplicate auto traits in trait object types
Fixes#12739
Chalk solver doesn't sort and deduplicate auto traits in trait object types, so we need to handle them ourselves in the lowering phase, just like [`rustc`](880416180b/compiler/rustc_typeck/src/astconv/mod.rs (L1487-L1488)) and [`chalk-integration`](https://github.com/rust-lang/chalk/blob/master/chalk-integration/src/lowering.rs#L575) do.
Quoting from [the Chalk book](https://rust-lang.github.io/chalk/book/types/rust_types.html#dyn-types):
> Note that -- for this purpose -- ordering of bounds is significant. That means that if you create a `dyn Foo + Send` and a `dyn Send + Foo`, chalk would consider them distinct types. The assumption is that bounds are ordered in some canonical fashion somewhere else.
Also, trait object types with more than one non-auto traits were previously allowed, but are now disallowed with this patch.
Use correct type in "Replace turbofish with type"
And support `?` and `.await` expressions.
Fixes#13148.
The assist can still show up even if the turbofish's type is not used at all, e.g.:
```rust
fn foo<T>() {}
let v = foo::<i32>();
```
I implemented that by checking the expressions' type.
This could probably be implemented better by taking the function's return type and substituting the generic parameter with the provided turbofish, but this is more complicated.
feat: Add a "Unmerge match arm" assist to split or-patterns inside match expressions
Fixes#13072.
The way I implemented it it leaves the `OrPat` in place even if there is only one pattern now but I don't think something will break because of that, and when more code will be typed we'll parse it again anyway. Removing it (but keeping the child pattern) is hard, I don't know how to do that.
Move empty diagnostics workaround back into the server
This only touches on the diagnostics in one place instead of multiple as was previously done, since all published diagnostics will go through this code path anyways.
Closes https://github.com/rust-lang/rust-analyzer/issues/13130
Make use of NoHash hashing for FileId and CrateId
Both of these are mere integers so there is nothing to hash here.
Ideally we would use this for `la_arena::Idx` too, but that doesn't work due to the orphan rule, and `la_arena` is unfortunately a public library so we can't really do much here... Unless we remove the trait restriction but I'd like not to
internal: Re-export standard semantic token types and mods
Should help in preventing future occurences of #13099 by having all token types and mods come through the same place