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.
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.
feat: Automatically add semicolon when completing unit-returning functions
But provide a config to suppress that.
I didn't check whether we are in statement expression position, because this is hard in completion (due to the natural incompleteness of source code when completion is invoked), and anyway using function returning unit as an argument to something seems... dubious.
Fixes#17263.
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.
Skip checks for cast to dyn traits
It seems that chalk fails to solve some obvious goals when there are some recursiveness in trait environments.
And it doesn't support trait upcasting yet. rust-lang/chalk#796
This PR just skips for casting into types containing `dyn Trait` to prevent false positive diagnostics like #18047 and #18083
This is a small change, but it was the cause of 90% of the errors in `rust-analyzer diagnostics .` 🫢
With this change and #18085 together, all remaining errors are type errors.
This may mean we can enable more errors, but this is out of scope for this PR.
internal: Add preliminary `SyntaxEditor` functionality
Related to #15710
Implements a `SyntaxEditor` interface to abstract over the details of modifying syntax trees, to both simplify creating new code fixes and code actions, as well as start on the path of getting rid of mutable syntax nodes.
`SyntaxEditor` relies on `SyntaxMappingBuilder`s to feed in the correct information to map AST nodes created by `make` constructors, as `make` constructors do not guarantee that node identity is preserved. This is to paper over the fact that `make` constructors simply re-parse text input instead of building AST nodes from the ground up and re-using the provided syntax nodes.
`SyntaxAnnotation`s are used to find where syntax elements have ended up after edits are applied. This is primarily useful for the `add_{placeholder,tabstop}` set of methods on `SourceChangeBuilder`, as that currently relies on the nodes provided being in the final syntax tree.
Eventually, the goal should be to move this into the `rowan` crate when we move away from mutable syntax nodes, but for now it'll stay in the `syntax` crate.
---
Closes#14921 as `SyntaxEditor` ensures that all replace changes are disjoint
Closes#9649 by implementing `SyntaxAnnotation`s
feat: better name suggestions for fn
fix#17631.
Better name suggestions for fn-calls / method-calls in the form of `from()`, `from_xxx()`, `into()`, etc.
But provide a config to suppress that.
I didn't check whether we are in statement expression position, because this is hard in completion (due to the natural incompleteness of source code when completion is invoked), and anyway using function returning unit as an argument to something seems... dubious.
`linkedProjects` is owned by the user's configuration, so when users
update this setting, `linkedProjects` is reset. This is problematic when
`linkedProjects` also contains projects discovered with `discoverCommand`.
The buggy behaviour occurred when:
(1) The user configures `discoverCommand` and loads a Rust project.
(2) The user changes any setting in VS Code, so rust-analyzer receives
`workspace/didChangeConfiguration`.
(3) `handle_did_change_configuration` ultimately calls
`Client::apply_change_with_sink()`, which updates `config.user_config`
and discards any items we added in `linkedProjects`.
Instead, separate out `discovered_projects_from_filesystem` and
`discovered_projects_from_command` from user configuration, so user
settings cannot affect any type of discovered project.
This fixes the subtle issue mentioned here:
https://github.com/rust-lang/rust-analyzer/pull/17246#issuecomment-2185259122
feat: Suggest name in completion for let_stmt and fn_param
fix#17780
1. Refactor: move `ide_assist::utils::suggest_name` to `ide-db::syntax_helpers::suggest_name` for reuse.
2. When completing `IdentPat`, detecte if the current node is a `let_stmt` or `fn_param`, and suggesting a new name based on the context.
fix: use Result type aliases in "Wrap return type in Result" assist
This commit makes the "Wrap return type in Result" assist prefer type aliases of standard library type when the are in scope, use at least one generic parameter, and have the name `Result`.
The last restriction was made in an attempt to avoid false assumptions about which type the user is referring to, but that might be overly strict. We could also do something like this, in order of priority:
* Use the alias named "Result".
* Use any alias if only a single one is in scope, otherwise:
* Use the standard library type.
This is easy to add if others feel differently that is appropriate, just let me know.
Fixes#17796
This commit makes the "Wrap return type in Result" assist prefer type aliases of standard library
type when the are in scope, use at least one generic parameter, and have the name "Result".
The last restriction was made in an attempt to avoid false assumptions about which type the
user is referring to, but that might be overly strict. We could also do something like this, in
order of priority:
* Use the alias named "Result".
* Use any alias if only a single one is in scope, otherwise:
* Use the standard library type.
This is easy to add if others feel differently that is appropriate, just let me know.
internal: Lay basic ground work for standalone mbe tests
Most of our mbe hir-def tests don't actually do anything name res relevant, we can (and should) move those down the stack into `mbe/hir-expand`.
Handle attributes correctly in "Flip comma"
Attributes often contain path followed by a token tree (e.g. `align(2)`), and the previous code handled them as two separate items, which led to results such as `#[repr(alignC, (2))]`.
An alternative is to just make the assist unavailable in attributes, like we do in macros. But contrary to macros, attributes often have a fixed form, so this seems useful.
Fixes#18013.
Attributes often contain path followed by a token tree (e.g. `align(2)`, and the previous code handled them as two separate items, which led to results such as `#[repr(alignC, (2))]`.
An alternative is to just make the assist unavailable in attributes, like we do in macros. But contrary to macros, attributes often have a fixed form, so this seems useful.
internal: Add doc comments to OpQueue
I spent a while debugging some OpQueue behaviours and found the API slightly confusing, so I've added doc comments to clarify what each OpQueue method does.
internal: Improve inlay hint resolution reliability
The payload now ships the range the inlay hint ought to be triggered for instead of trying to estimate it from its position which is somewhat brittle
Do not report missing unsafe on `addr_of[_mut]!(EXTERN_OR_MUT_STATIC)`
The compiler no longer does as well; see https://github.com/rust-lang/rust/pull/125834.
Also require unsafe when accessing `extern` `static` (other than by `addr_of!()`).
Fixes#17978.
fix: `std::error::Error` is object unsafe
Fixes#17998
I tried to get generic predicates of assoc function itself, not inherited from the parent here;
0ae42bd425/crates/hir-ty/src/object_safety.rs (L420-L442)
But this naive equality check approach doesn't work when the assoc function has one or more generic paramters like;
```rust
trait Foo {}
trait Bar: Foo {
fn bar(&self);
}
```
because the generic predicates of the parent, `Bar` is `[^1.0 implements Foo]` and the generic predicates of `fn bar` is `[^1.1 implements Foo]`, which are different.
This PR implements a correct logic for filtering out parent generic predicates for this.
This makes the generated impl's indentation match the ADT it targets, improving formatting when
using nested modules inside of the same file or when defining types inside of a function.
Consider field attributes when converting from tuple to named struct and the opposite
Fixes#17983.
I tried to use the `SourceChangeBuilder::make_mut()` API, but it duplicated the attribute...
fix: Don't add reference when it isn't needed for the "Extract variable" assist
I.e. don't generate `let var_name = &foo()`. Because it always irritates me when I need to fix that.
Anything that creates a new value don't need a reference. That excludes mostly field accesses and indexing.
I had a thought that we can also not generate a reference for fields and indexing as long as the type is `Copy`, but sometimes people impl `Copy` even when they don't want to copy the values (e.g. a large type), so I didn't do that.
Fix incorrect symbol definitions in SCIP output
The SCIP output incorrectly marks some symbols as definitions because it doesn't account for the file ID when comparing the token's range to its definition's range.
This means that if a symbol is referenced in a file at the same position at which it is defined in another file, that reference will be marked as a definition. I was quite surprised by how common this is. For example, `PartialEq` is defined [here](https://github.com/rust-lang/rust/blob/1.80.1/library/core/src/cmp.rs#L273) and `uuid` references it [here](https://github.com/uuid-rs/uuid/blob/1.8.0/src/lib.rs#L329). And what do you know, they're both at offset 10083! In our large monorepo, this happens for basically every common stdlib type!
feat: Create an assist to convert closure to freestanding fn
The assist converts all captures to parameters.
Closes#17920.
This was more work than I though, since it has to handle a bunch of edge cases...
Based on #17941. Needs to merge it first.
internal: Avoid newlines in fetch errors
Most logs lines don't have newlines, ensure fetch errors follow this pattern. This makes it easier to see which log line is associated with the error.
Before:
2024-08-28T21:11:58.431856Z ERROR FetchWorkspaceError:
rust-analyzer failed to discover workspace
After:
2024-08-28T21:11:58.431856Z ERROR FetchWorkspaceError: rust-analyzer failed to discover workspace
I.e. don't generate `let var_name = &foo()`.
Anything that creates a new value don't need a reference. That excludes mostly field accesses and indexing.
I had a thought that we can also not generate a reference for fields and indexing as long as the type is `Copy`, but sometimes people impl `Copy` even when they don't want to copy the values (e.g. a large type), so I didn't do that.
Expand proc-macros in workspace root, not package root
Should fix https://github.com/rust-lang/rust-analyzer/issues/17748. The approach is generally not perfect though as rust-project.json projects don't benefit from this (still, nothing changes in that regard)