Fix extract variable assist for subexpression in mutable borrow
This checks if the expression is in a mutable borrow and if so makes the extracted variable `mut`.
Closes#12786
ToString is implemented by many different types than &str, and
represents a serialization into string data. The fact that said data is
returned as owned, is an implementation detail.
If merely copying borrowed string data to owned string data is all that
is desired, ToOwned is a much better choice, because if the user later
refactors the code such that the input is no longer an `&str`, then they
will get a compiler error instead of a mysterious change-in-behavior.
internal: Record all macro definitions in ItemScope
Fixes https://github.com/rust-lang/rust-analyzer/issues/12100
Doesn't resolve the shadowing issues though, fixing those is gonna be really tricky I believe unless we can come up with a nice scheme to "order" item tree items (using syntax ranges and file ids would be a pain and also a bad idea since that'll require us to potentially reparse files in collection).
Automatically instaciate trivially instaciable structs in "Generate new" and "Fill struct fields"
As proposed in #12535 this PR changes the "Generate new" and "Fill struct fields" assist/diagnostic to instanciate structs with no fields and enums with a single empty variant.
For example:
```rust
pub enum Bar {
Bar {},
}
struct Foo<T> {
a: usize,
bar: Bar,
_phantom: std::marker::PhantomData<T>,
}
impl<T> Foo<T> {
/* generate new */
fn random() -> Self {
Self { /* Fill struct fields */ }
}
}
```
was previously:
```rust
impl<T> Foo<T> {
fn new(a: usize, bar: Bar, _phantom: std::marker::PhantomData<T>) -> Self {
Self { a, bar, _phantom }
}
fn random() -> Self {
Self {
a: todo!(),
bar: todo!(),
_phantom: todo!(),
}
}
}
```
and is now:
```rust
impl<T> Foo<T> {
fn new(a: usize) -> Self {
Self {
a,
bar: Bar::Bar {},
_phantom: std::marker::PhantomData
}
}
fn random() -> Self {
Self {
a: todo!(),
bar: Bar::Bar {},
_phantom: std::marker::PhantomData,
}
}
}
```
I'd be happy about any suggestions.
## TODO
- [x] deduplicate `use_trivial_constructor` (unclear how to do as it's used in two separate crates)
- [x] write tests
Closes#12535
- allow appending tokens after a token, not just a node
- allow inserting delimiters (and remove them again)
- fix up `if {}` and `if` without anything following
fix: Support generics in extract_function assist
This change attempts to resolve issue #7636: Extract into Function does not
create a generic function with constraints when extracting generic code.
In `FunctionBody::analyze_container`, we now traverse the `ancestors` in search
of `AnyHasGenericParams`, and attach any `GenericParamList`s and `WhereClause`s
we find to the `ContainerInfo`.
Later, in `format_function`, we collect all the `GenericParam`s and
`WherePred`s from the container, and filter them to keep only types matching
`TypeParam`s used within the newly extracted function body or param list. We
can then include the new `GenericParamList` and `WhereClause` in the new
function definition.
This change only impacts `TypeParam`s. `LifetimeParam`s and `ConstParam`s are
out of scope for this change.
I've never contributed to this project before, but I did try to follow the style guide. I believe that this change represents an improvement over the status quo, but I think it's also fair to argue that it doesn't fully "fix" the linked issue. I'm totally open to merging this as is, or going further to try to make a more complete solution. Also: if there are other unit or integration tests I should add, please let me know where to look!
This change attempts to resolve issue #7636: Extract into Function does not
create a generic function with constraints when extracting generic code.
In `FunctionBody::analyze_container`, we now traverse the `ancestors` in search
of `AnyHasGenericParams`, and attach any `GenericParamList`s and `WhereClause`s
we find to the `ContainerInfo`.
Later, in `format_function`, we collect all the `GenericParam`s and
`WherePred`s from the container, and filter them to keep only types matching
`TypeParam`s used within the newly extracted function body or param list. We
can then include the new `GenericParamList` and `WhereClause` in the new
function definition.
This change only impacts `TypeParam`s. `LifetimeParam`s and `ConstParam`s are
out of scope for this change.
Fix obsolete config keys
The config keys were drastically reorganized by #12010, but the docs don't reflect the updates, causing inconsistency and confusion. I checked for such obsolete configuration keys and updated to the new one. For reproducibility, I attach a small shell script that I used to examine the old keys. Now the script only detects `cargoExtraArgs` and `overrideCargo`, which originates from other type definition in the code but not from the configuration.
<details><summary>script</summary>
```bash
echo "allowMergingIntoGlobImports
exprFillDefault
importEnforceGranularity
importGranularity
importMergeBehavior
importMergeBehaviour
importGroup
importPrefix
warmup
loadOutDirsFromCheck
runBuildScripts
runBuildScriptsCommand
useRustcWrapperForBuildScripts
enableExperimental
procAttrMacros
breakPoints
exitPoints
yieldPoints
linksInHover
linksInHover
gotoTypeDef
chainingHints
closureReturnTypeHints
hideNamedConstructorHints
parameterHints
reborrowHints
typeHints
lruCapacity
cargoExtraArgs
overrideCargo
rustcSource
enableRangeFormatting
assist\.allowMergingIntoGlobImports
assist\.exprFillDefault
assist\.importEnforceGranularity
assist\.importGranularity
assist\.importMergeBehavior
assist\.importMergeBehaviour
assist\.importGroup
assist\.importPrefix
primeCaches\.enable
cache\.warmup
cargo\.loadOutDirsFromCheck
cargo\.runBuildScripts
cargo\.runBuildScriptsCommand
cargo\.useRustcWrapperForBuildScripts
completion\.snippets
diagnostics\.enableExperimental
experimental\.procAttrMacros
highlighting\.strings
highlightRelated\.breakPoints
highlightRelated\.exitPoints
highlightRelated\.yieldPoints
highlightRelated\.references
hover\.documentation
hover\.linksInHover
hoverActions\.linksInHover
hoverActions\.debug
hoverActions\.enable
hoverActions\.gotoTypeDef
hoverActions\.implementations
hoverActions\.references
hoverActions\.run
inlayHints\.chainingHints
inlayHints\.closureReturnTypeHints
inlayHints\.hideNamedConstructorHints
inlayHints\.parameterHints
inlayHints\.reborrowHints
inlayHints\.typeHints
lruCapacity
runnables\.cargoExtraArgs
runnables\.overrideCargo
rustcSource
rustfmt\.enableRangeFormatting
allFeatures
addCallArgumentSnippets
addCallParenthesis
callInfo\.full
cargo\.allFeatures
checkOnSave\.allFeatures
completion\.addCallArgumentSnippets
completion\.addCallParenthesis" | while read -r pattern
do
rg '\b'$pattern'\b([^.]|$)' . -g "!crates/rust-analyzer/src/config/patch_old_style.rs" -g "!editors/code/src/config.ts" -g "!a.sh" --no-heading --color=always --line-number
done
exit
excluded
# debug
# enable
# run
# implementations
# references
# documentation
# references
# snippets
# strings
# full
```
</details>
When extracting a field expression, if RA was unable to resolve the type of the
field, we would previously fall back to using "var_name" as the variable name.
Now, when the `Expr` being extracted matches a `FieldExpr`, we can use the
`NameRef`'s ident token as a fallback option.
fixes#10035
This change fixes#12705.
In `FunctionBody::analyze`, we need to search any `ClosureExpr`s we encounter
for any `NameRef`s, to ensure they aren't missed.
fix: Extract function from trait impl
This change fixes#10036, "Extract to function assist implements nonexistent
trait methods".
When we detect that the extraction is coming from within a trait impl, and that
a `self` param will be necessary, we adjust which `SyntaxNode` to `insert_after`,
and create a new empty `impl` block for the newly extracted function.
This change fixes#10036, "Extract to function assist implements nonexistent
trait methods".
When we detect that the extraction is coming from within a trait impl, and that
a `self` param will be necessary, we adjust which `SyntaxNode` to `insert_after`,
and create a new empty `impl` block for the newly extracted function.
This change fixes issue #10037, in more or less the most naive fashion
possible.
We continue to start with the hardcoded default of "fun_name", and now append a
counter to the end of it if that name is already in scope.
In the future, we can probably apply more heuristics here to wind up with more
useful names by default, but for now this resolves the immediate problem.
fix: Simplify macro statement expansion handling
I only meant to fix https://github.com/rust-lang/rust-analyzer/issues/12644 but that somehow turned into a rewrite of the statement handling ... at least this fixes a few more issues in the IDE layer now
fix: improve whitespace insertion in pretty printer
Fixes#12591
The `=>` token in the macro_rules! should be parsed as one fat arrow, but it ["requires a lot of changes in r-a"](143cc528b1), so I left it for the larger refactoring in the future and put a FIXME note.
feat: Show witnesses of non-exhaustiveness in `missing-match-arm` diagnostic
Shamelessly copied from rustc. Thus reporting format is same.
This extends public api `hir::diagnostics::MissingMatchArms` with `uncovered_patterns: String` field. It does not expose data for implementing a quick fix yet.
-----
Worth to note: current implementation does not give a comprehensive list of missing patterns. Also mentioned in [paper](http://moscova.inria.fr/~maranget/papers/warn/warn.pdf):
> One may think that algorithm I should make an additional effort to provide more
> non-matching values, by systematically computing recursive calls on specialized
> matrices when possible, and by returning a list of all pattern vectors returned by
> recursive calls. We can first observe that it is not possible in general to supply the
> users with all non-matching values, since the signature of integers is (potentially)
> infinite.
fix: trailing ':' on empty inactive reasons
## Description
Fixes trailing ':' even when there is no explanation. e.g.
``` sh
code is inactive due to #[cfg] directives:
```
## Issue
Fixes: #12615
feat: implement destructuring assignment
This is an attempt to implement destructuring assignments, or more specifically, type inference for [assignee expressions](https://doc.rust-lang.org/reference/expressions.html#place-expressions-and-value-expressions).
I'm not sure if this is the right approach, so I don't even expect this to be merged (hence the branch name 😉) but rather want to propose one direction we could choose. I don't mind getting merged if this is good enough though!
Some notes on the implementation choices:
- Assignee expressions are **not** desugared on HIR level unlike rustc, but are inferred directly along with other expressions. This matches the processing of other syntaxes that are desugared in rustc but not in r-a. I find this reasonable because r-a only needs to infer types and it's easier to relate AST nodes and HIR nodes, so I followed it.
- Assignee expressions obviously resemble patterns, so type inference for each kind of pattern and its corresponding assignee expressions share a significant amount of logic. I tried to reuse the type inference functions for patterns by introducing `PatLike` trait which generalizes assignee expressions and patterns.
- This is not the most elegant solution I suspect (and I really don't like the name of the trait!), but it's cleaner and the change is smaller than other ways I experimented, like making the functions generic without such trait, or making them take `Either<ExprId, PatId>` in place of `PatId`.
in case this is merged:
Closes#11532Closes#11839Closes#12322
fix: Improve proc macro errors a bit
Distinguish between
- there is no build data (for some reason?)
- there is build data, but the cargo package didn't build a proc macro dylib
- there is a proc macro dylib, but it didn't contain the proc macro we expected
- the name did not resolve to any macro (this is now an
unresolved_macro_call even for attributes)
I changed the handling of disabled attribute macro expansion to
immediately ignore the macro and report an unresolved_proc_macro,
because otherwise they would now result in loud unresolved_macro_call
errors. I hope this doesn't break anything.
Also try to improve error ranges for unresolved_macro_call / macro_error
by reusing the code for unresolved_proc_macro. It's not perfect but
probably better than before.
Distinguish between
- there is no build data (for some reason?)
- there is build data, but the cargo package didn't build a proc macro dylib
- there is a proc macro dylib, but it didn't contain the proc macro we expected
- the name did not resolve to any macro (this is now an
unresolved_macro_call even for attributes)
I changed the handling of disabled attribute macro expansion to
immediately ignore the macro and report an unresolved_proc_macro,
because otherwise they would now result in loud unresolved_macro_call
errors. I hope this doesn't break anything.
Also try to improve error ranges for unresolved_macro_call / macro_error
by reusing the code for unresolved_proc_macro. It's not perfect but
probably better than before.
fix: doc_links link type - Determine link type at start (fixes#12601)
fixes#12601
Looked like autolink/inline mismatch happened because end_link_type was parsed from the Text/Code events.
I changed it to be determined from the Start event, which should hopefully remain accurate while staying true to the cases where link type may need to be changed, according to the comment
```
// normally link's type is determined by the type of link tag in the end event,
// however in some cases we want to change the link type, for example,
// `Shortcut` type doesn't make sense for url links
```
Hopefully this is the desired behavior?
![Untitled](https://user-images.githubusercontent.com/59463268/174696581-3b1140a5-cdf0-4eda-9a11-ec648e4e7d21.gif)
- remove Valid, it serves no purpose and just obscures the diff
- rename some things
- don't use is_valid_candidate when searching for impl, it's not necessary
fix: Only apply `cfg(test)` for local crates
Don't analyze dependencies with `test`; this should fix various cases where crates use `cfg(not(test))` and so we didn't find things.
"Local" here currently means anything that's not from the registry, so anything inside the workspace, but also path dependencies. So this isn't perfect, and users might still need to use `rust-analyzer.cargo.unsetTest` for these in some cases.
Don't analyze dependencies with `test`; this should fix various cases
where crates use `cfg(not(test))` and so we didn't find things.
"Local" here currently means anything that's not from the registry, so
anything inside the workspace, but also path dependencies. So this isn't
perfect, and users might still need to use
`rust-analyzer.cargo.unsetTest` for these in some cases.
fix: local items should not be completed in parent signature
fixes#11959
> We get a Bar completion for the following snippet which is wrong as the item is not visible in that position.
> ``` rust
> fn foo() -> $0 {
> struct Bar;
> }
> ```
I investigated the problem and found that the scope of the cursor offset, also `CompletionContext.scope` is the body of the function
fix methods in pub trait generated by macro cannot be completed
Fix#12483
Check if the container is trait and inherit the visibility to associate items during collection.