bugfix : skip doc(hidden) default members
fixes #14957 . I have two questions :
1. I am definitely looking for a more idiomatic way for the things I added in `crates/ide-assists/src/utils.rs`. See `FIXME` in that file.
2. Would it be actually better to change `DefaultMethods` to something like
```rust
enum DefaultMethods {
Only( IgnoreHidden ( bool ) ) ,
None
}
```
instead of adding a boolean to every function that calls `crates/ide-assists/src/utils.rs::filter_assoc_items`
internal: Migrate assists to the structured snippet API, part 3
Continuing from #15231
Migrates the following assists:
- `add_missing_match_arms`
- `fix_visibility`
- `promote_local_to_const`
The `add_missing_match_arms` changes are best reviewed commit-by-commit since they're relatively big changes compared to the rest of the commits.
`clone_for_update` is relatively cheap in comparison, since making a
node require parsing an entire source text
Adds a test to make sure that it doesn't crash when multiple uses are
present.
internal: Migrate more assists to use the structured snippet API
Continuing from #14979
Migrates the following assists:
- `generate_derive`
- `wrap_return_type_in_result`
- `generate_delegate_methods`
As a bonus, `generate_delegate_methods` now generates the function and impl block at the correct indentation 🎉.
`does_not_fill_wildcard_with_wildcard`
and `does_not_fill_wildcard_with_partial_wildcard_and_wildcard`
both made no modifications to the code,
which is a problem for mutable ast porting as it generates a best-effort
minimal set of text edits,
and assists require at least one text edit.
# Overview
Extracting a match arm value that has type unit into a function, when a
comma already follows the match arm value, results in an invalid (syntax
error) semicolon added between the newly generated function's generated
call and the comma.
# Example
Running this extraction
```rust
fn main() {
match () {
_ => $0()$0,
};
}
```
would lead to
```rust
fn main() {
match () {
_ => fun_name();,
};
}
fn fun_name() {
}
```
# Issue / Fix details
This happens because when there is no comma, rust-analyzer would simply
add the comma and wouldn't even try to evaluate whether it needs to add
a semicolon. But when the comma is there, it proceeds to evaluate
whether it needs to add a semicolon and it looks like the evaluation
logic erroneously ignores the possibility that we're in a match arm.
IIUC it never makes sense to add a semicolon when we're extracting from
a match arm value, so I've adjusted the logic to always decide against
adding a semicolon when we're in a match arm
Can actually split out adding the functions from getting the impl to
update or create thanks to being able to refer to the impl ast node.
FIXME Context:
Unfortunately we can't adjust the indentation of the newly added function
inside of `ast::AssocItemList::add_item` since for some reason the `todo!()`
placeholder generated by `add_missing_impl_members` and
`replace_derive_with_manual_impl` gets indented weirdly.
Unify getter and setter assists
This PR combines what previously have been two different files into a single file. I want to talk about the reasons why I did this. The issue that prompted this PR ( and before I forget : this pr fixes#15080 ) mentions an interesting behavior. We combine these two assists into an assist group and the order in which the assists are listed in this group changes depending on the text range of the selected area. The reason for that is that VSCode prioritizes actions that have a bigger impact in a smaller area and until now generate setter assist was only possible to be invoked for a single field whereas you could generate multiple getters for the getter assist. So I used the latter's infra to make former applicable to multiple fields, hence the unification. So this PR solves in essence
1. Make `generate setter` applicable to multiple fields
2. Provide a consistent order of the said assists in listing.
assist : generate trait from impl
fixes#14987 . As the name suggests this assist is used to generate traits from inherent impls while adapting the original impl to fit to the newly generated trait. I made some decisions regarding when the assist should be applicable. These are surely open to discussion. I looking forward to any feedback.
![generate_trait_from_impl_v1](https://github.com/rust-lang/rust-analyzer/assets/20956650/05d4dda5-604a-4108-8b82-9b60bd45894a)
internal: Format let-else
As nightly finally got support for it I went ahead and formatted r-a with the latest nightly, then with the latest stable (in case other stuff changed)
Clean up `ImportMap`
There are several things in `hir_def::import_map` that are never used. This PR removes them and restructures the code. Namely:
- Removes `Query::name_only`, because it's *always* true.
- Because of this, we never took advantage of storing items' full path. This PR removes `ImportPath` and changes `ImportInfo` to only store items' name, which should reduce the memory consumption to some extent.
- Removes `SearchMode::Contains` for `Query` because it's never used.
- Merges `Query::assoc_items_only` and `Query::exclude_import_kinds` into `Query::assoc_mode`, because the latter is never used besides filtering associated items out.
Best reviewed one commit at a time. I made sure each commit passes full test suite. I can squash the first three commits if needed.
feature : assist delegate impl
This PR ( fixes#14386 ) introduces a new IDE assist that generates a trait impl for a struct that delegates a field. This is a draft because the current `ide_db::path_transform::PathTransform` produces some unwanted results when it deals with extern crates, an example of which I attach as a GIF.
GIFs :
1. A general case
![14386-functional](https://github.com/rust-lang/rust-analyzer/assets/20956650/22114959-caa6-45ec-a154-b4b2f458f6b1)
2. A case where `ide_db::path_transform::PathTransform` fails to correctly resolve a property ( take `Allocator` as an example ) to its full path, thus causing an error to occur. ( Not to even mention that resolving this causes another error `use of unstable library feature 'allocator_api'` to occur
![14386-erroneous](https://github.com/rust-lang/rust-analyzer/assets/20956650/922ca715-594e-4168-a579-7c5c006f93aa)
Remove scope_for_def calls as the definition have been removed entirely.
As a result of this change the problem with false path resolutions has been solved.
Lower const params with a bad id
cc #7434
This PR adds an `InTypeConstId` which is a `DefWithBodyId` and lower const generic parameters into bodies using it, and evaluate them with the mir interpreter. I think this is the last unimplemented const generic feature relative to rustc stable.
But there is a problem: The id used in the `InTypeConstId` is the raw `FileAstId`, which changes frequently. So these ids and their bodies will be invalidated very frequently, which is bad for incremental analysis.
Due this problem, I disabled lowering for local crates (in library crate the id is stable since files won't be changed). This might be overreacting (const generic expressions are usually small, maybe it would be better enabled with bad performance than disabled) but it makes motivation for doing it in the correct way, and it splits the potential panic and breakages that usually comes with const generic PRs in two steps.
Other than the id, I think (at least I hope) other parts are in the right direction.
fix: implemeted lifetime transformation fot assits
A part of https://github.com/rust-lang/rust-analyzer/issues/13363
I expect to implement transformation of const params in a separate PR
Other assists and a completion affected:
- `generate_function` currently just ignores lifetimes and, consequently, is not affected
- `inline_call` and `replace_derive_with...` don't seem to need lifetime transformation
- `trait_impl` (a completion) is fixed and tested
internal: Migrate some assists to use the structured snippet API
Migrates the following assists:
- `add_missing_impl_members`
- `extract_type_alias`
As an additional requirement, these assists are also migrated to use the mutable AST API, since otherwise there would be overlapping `Indel` spans
The change updates the logic to determine if a function parameter is
valid for replacing the type param with the trait implementation.
First all usages are determined, to check if they are used outside the function
parameter list. If an outside reference is found, e.g. in body, return type or
where clause, the assist is skipped. All remaining usages only appear in the
function param list. For each usage the param type is checked to see if
it's valid.
**Please note** the logic currently follows a heuristic and may not cover
all existing parameter declarations.
* determine valid usage references by checking ancestors (on AST level)
* split test into separate ones
Fix edits for `convert_named_struct_to_tuple_struct`
Two fixes:
- When replacing syntax nodes, macro files weren't taken into account. Edits were simply made for `node.syntax().text_range()`, which would be wrong range when `node` is inside a macro file.
- We do ancestor node traversal for every struct name reference to find record expressions/patterns to edit, but we didn't verify that expressions/patterns do actually refer to the struct we're operating on.
Best reviewed one commit at a time.
Fixes#13780Fixes#14927
Previously we didn't verify that record expressions/patterns that were
found did actually point to the struct we're operating on. Moreover,
when that record expressions/patterns had missing child nodes, we would
continue traversing their ancestor nodes.
This removes an existing generic param from the `GenericParamList`. It
also considers to remove the extra colon & whitespace to the previous
sibling.
* change order to get all param types first and mark them as mutable
before the first edit happens
* add helper function to remove a generic parameter
* fix test output
This adds a new assist named "replace named generic with impl" to move
the generic param type from the generic param list into the function
signature.
```rust
fn new<T: ToString>(input: T) -> Self {}
```
becomes
```rust
fn new(input: impl ToString) -> Self {}
```
The first step is to determine if the assist can be applied, there has
to be a match between generic trait param & function paramter types.
* replace function parameter type(s) with impl
* add new `impl_trait_type` function to generate the new trait bounds with `impl` keyword for use in the
function signature
fix: assists no longer break indentation
Fixes https://github.com/rust-lang/rust-analyzer/issues/14674
These are _ad hoc_ patches for a number of assists that can produce incorrectly indented code, namely:
- generate_derive
- add_missing_impl_members
- add_missing_default_members
Some general solution is required in future, as the same problem arises in many other assists, e.g.
- replace_derive_with...
- generate_default_from_enum...
- generate_default_from_new
- generate_delegate_methods
(the list is incomplete)
Restrict "sort items" assist for traits & impls
This restricts the "sort items alphabetically" assist when the selection is inside a `Impl` or `Trait` node & intersects with one of the associated items.
It re-orders the conditional checks of AST nodes in the `sort_items` function to check for more specific nodes first before checking `Trait` or `Impl` nodes. The `AssistContext` is passed into the `add_sort_methods_assist` function to check if the selection intersects with any inner items, e.g. associated const or type alias, function. In this case the assist does not apply.
Fixes: #14516