feat: Support the `${concat(...)}` metavariable expression
I didn't follow rustc precisely, because I think it does some things wrongly (or they are FIXME), but I only allowed more code, not less. So we're all fine.
Closes#18145.
fix: Handle lint attributes that are under `#[cfg_attr]`
I forgot `cfg_attr` while working on #18099. Although the original code also didn't handle that (although case lints specifically were correct, by virtue of using hir attrs).
fix: When checking for forbidden expr kind matches, account for rawness
An expression starting with `r#const` etc. should be accepted even in edition <=2021.
Fixes#18148.
This was not fixed when testing with edition 2024, I wonder whether that means our check for edition is incorrect...
I didn't follow rustc precisely, because I think it does some things wrongly (or they are FIXME), but I only allowed more code, not less. So we're all fine.
fix: Remove check that text of `parse_expr_from_str()` matches the produced parsed tree
This check is incorrect when we have comments and whitespace in the text.
We can strip comments, but then we still have whitespace, which we cannot strip without changing meaning for the parser. So instead I opt to remove the check, and wrap the expression in parentheses (asserting what produced is a parenthesized expression) to strengthen verification.
Fixes#18144.
This check is incorrect when we have comments and whitespace in the text.
We can strip comments, but then we still have whitespace, which we cannot strip without changing meaning for the parser. So instead I opt to remove the check, and wrap the expression in parentheses (asserting what produced is a parenthesized expression) to strengthen verification.
fix: Get rid of `$crate` in expansions shown to the user
Be it "Expand Macro Recursively", "Inline macro" or few other things.
We replace it with the crate name, as should've always been.
Probably fixes some issues, but I don't know what they are.
fix: Extend `type_variable_table` when modifying index is larger than the table size
Fixes#18109
Whenever we create an inference variable in r-a, we extend `type_variable_table` to matching size here;
f4aca78c92/crates/hir-ty/src/infer/unify.rs (L378-L381)
But sometimes, an inference variable is [created from chalk](ab710e0c9b/chalk-solve/src/infer/unify.rs (L743)) and passed to r-a as a type of an expression or a pattern.
If r-a set diverging flag to this before the table is extended to a sufficient size, it panics here;
f4aca78c92/crates/hir-ty/src/infer/unify.rs (L275-L277)
I think that extending table when setting diverging flag is reasonable becase we are already doing such extending to a size that covers the inference vars created from chalk and this change only covers the order-dependent random cases that this might fail
fix: Always cache macro expansions' root node in Semantics
Previously some expansions were not cached, but were cached in the expansion cache, which caused panics when later queries tried to lookup the node from the expansion cache.
Fixes#18089.
fix: Handle errors and lints from external macros
Some lints should not be reported if they originate from an external macro, and quickfixes should be disabled (or they'll change library code).
Fixes#18122.
Closes#18124.
Don't lint names of #[no_mangle] extern fns
[Rust doesn't run the `non_snake_case_name` lint on `extern fn`s with the `#[no_mangle]` attribute](https://github.com/rust-lang/rust/pull/44966).
The conditions are:
- The function must be `extern` and have a `#[no_mangle]` attribute.
- The function's ABI must not be explicitly set to "Rust".
This PR replicates that logic here.
internal: Extend SourceChangeBuilder to make make working with `SyntaxEditor`s easier
Part of #15710
Adds additional `SourceChangeBuilder` methods to make it easier to migrate assists to `SyntaxEditor`.
As `SyntaxEditor`s are composable before they're completed, each created `SyntaxEditor` can represent logical groups of changes (e.g. independently performing renames of uses in a file from inserting the new item). Once a group of changes is considered "done", `SourceChangeBuilder::add_file_edits` is used to submit a set of changes to be part of the source change.
`SyntaxAnnotation`s are used to indicate where snippets are attached to, and using `SyntaxAnnotation`s also means that we can attach snippets at any time, rather than being required to be after all edits.
Previously some expansions were not cached, but were cached in the expansion cache, which caused panics when later queries tried to lookup the node from the expansion cache.
Use more correct handling of lint attributes
The previous analysis was top-down, and worked on a single file (expanding macros). The new analysis is bottom-up, starting from the diagnostics and climbing up the syntax and module tree.
While this is more efficient (and in fact, efficiency was the motivating reason to work on this), unfortunately the code was already fast enough. But luckily, it also fixes a correctness problem: outline parent modules' attributes were not respected for the previous analysis. Case lints specifically did their own analysis to accommodate that, but it was limited to only them. The new analysis works on all kinds of lints, present and future.
It was basically impossible to fix the old analysis without rewriting it because navigating the module hierarchy must come bottom-up, and if we already have a bottom-up analysis (including syntax analysis because modules can be nested in other syntax elements, including macros), it makes sense to use only this kind of analysis.
Few other bugs (not fundamental to the previous analysis) are also fixed, e.g. overwriting of lint levels (i.e. `#[allow(lint)] mod foo { #[warn(lint)] mod bar; }`.
After this PR is merged I intend to work on an editor command that does workspace-wide diagnostics analysis (that is, `rust-analyzer diagnostics` but from your editor and without having to spawn a new process, which will have to analyze the workspace from scratch). This can be useful to users who do not want to enable check on save because of its overhead, but want to see workspace wide diagnostics from r-a (or to maintainers of rust-analyzer).
Closes#18086.
Closes#18081.
Fixes#18056.
The previous analysis was top-down, and worked on a single file (expanding macros). The new analysis is bottom-up, starting from the diagnostics and climbing up the syntax and module tree.
While this is more efficient (and in fact, efficiency was the motivating reason to work on this), unfortunately the code was already fast enough. But luckily, it also fixes a correctness problem: outline parent modules' attributes were not respected for the previous analysis. Case lints specifically did their own analysis to accommodate that, but it was limited to only them. The new analysis works on all kinds of lints, present and future.
It was basically impossible to fix the old analysis without rewriting it because navigating the module hierarchy must come bottom-up, and if we already have a bottom-up analysis (including syntax analysis because modules can be nested in other syntax elements, including macros), it makes sense to use only this kind of analysis.
Few other bugs (not fundamental ti the previous analysis) are also fixed, e.g. overwriting of lint levels (i.e. `#[allow(lint)] mod foo { #[warn(lint)] mod bar; }`.
feat: generate names for tuple-struct in add-missing-match-arms
fix#18034.
This PR includes the following enhancement:
- Introduced a `NameGenerator` in `suggest_name`, which implements an automatic renaming algorithm to avoid name conflicts. Here are a few examples:
```rust
let mut generator = NameGenerator::new();
assert_eq!(generator.suggest_name("a"), "a");
assert_eq!(generator.suggest_name("a"), "a1");
assert_eq!(generator.suggest_name("a"), "a2");
assert_eq!(generator.suggest_name("b"), "b");
assert_eq!(generator.suggest_name("b"), "b1");
assert_eq!(generator.suggest_name("b2"), "b2");
assert_eq!(generator.suggest_name("b"), "b3");
assert_eq!(generator.suggest_name("b"), "b4");
assert_eq!(generator.suggest_name("b3"), "b5");
```
- Updated existing testcases in ide-assists for the new `NameGenerator` (only modified generated names).
- Generate names for tuple structs instead of using wildcard patterns in `add-missing-match-arms`.
fix: Faulty notifications should not bring down the server
Fixes https://github.com/rust-lang/rust-analyzer/issues/18055, if a client sends us an unregistered document path in a did save notification it would force us to exit the thread. That is obviously not great behavior, we should be more fallible here
feat: render patterns in params for hovering
Fix#17858
This PR introduces an option to [hir-def/src/body/pretty.rs](08c7bbc2db/crates/hir-def/src/body/pretty.rs) to render the result as a single line, which is then reused for rendering patterns in parameters for hovering.
assist: ensure `replace_qualified_name_with_use` applies to the first path segment
This change helps a bit with the discoverability of `replace_qualified_name_with_use`. Specifically, it ensures that a cursor on the first path segment (e.g., `$0std::fmt::Debug`, where `$0` is the cursor) would result in an import along the lines of `use std::fmt;` and `fmt::Debug;` at the usage sites.
internal: Better testing infra for ratoml
This PR makes some improvements on how we test configs that come from `rust-analyzer.toml` files.
It was primarily used to solve #18021 but along the way I could not really determine the cause of the said issue which makes me think that it may not be related to the changes that I made earlier to the ratoml infra. In either way `custom_snippets` are now made `global` because we still don't have a tree that maps a `SourceRootId` to a set of `Snippet`s.
fix: Fix `inline_const_as_literal` error when the number >= 10
## Description
### The Bug
This PR fixes a small bug in the IDE assistence (`inline_const_as_literal`). When the being-inlined constant is a number and it is greater than or equal to 10, the assistence inserts unexpected string `(0x...)` after the number itself. A simple example is followed:
Current `inline_const_as_literal` changes
```rs
const A: usize = 16;
fn f() -> usize {
A // inline the constant
}
```
into
```rs
const A: usize = 16;
fn f() -> usize {
16 (0x10)
}
```
The bug originates from #14925 & #15306 . #14925 added some unittests, but it just tested the number-inlining behavior when the number is `0`.
50882fbfa2/crates/ide-assists/src/handlers/inline_const_as_literal.rs (L124-L138)
And #15306 modified the behavior of `Const::render_eval` and added the `(0x...)` part after the number (if the number >= `10`). Because of insufficient unittests in #14925, changes about `Const::render_eval` in #15306 introduced this bug with no CI failure.
### The Fix
I think `Const::render_eval` is intended for user-facing value displaying (e.g. hover) and not designed for `inline_const_as_literal`. To fix the bug, I defined a new function named `Const::eval`, which evaluates the value itself faithfully and simply and does nothing else.
## Thanks
Thanks `@roife` for your kind help. Your guidance helped me better understand the code.