fix: make bool_to_enum assist create enum at top-level
This pr makes the `bool_to_enum` assist create the `enum` at the next closest module block or at top-level, which fixes a few tricky cases such as with an associated `const` in a trait or module:
```rust
trait Foo {
const $0BOOL: bool;
}
impl Foo for usize {
const BOOL: bool = true;
}
fn main() {
if <usize as Foo>::BOOL {
println!("foo");
}
}
```
Which now properly produces:
```rust
#[derive(PartialEq, Eq)]
enum Bool { True, False }
trait Foo {
const BOOL: Bool;
}
impl Foo for usize {
const BOOL: Bool = Bool::True;
}
fn main() {
if <usize as Foo>::BOOL == Bool::True {
println!("foo");
}
}
```
I also think it's a bit nicer, especially for local variables, but didn't really know to do it in the first PR :)
fix: panic with wrapping/unwrapping result return type assists
With the `wrap_return_type_in_result` assist, the following code results in a panic (note the lack of a semicolon):
```rust
fn foo(num: i32) -> $0i32 {
return num
}
=>
thread 'handlers::wrap_return_type_in_result::tests::wrap_return_in_tail_position' panicked at crates/syntax/src/ted.rs:137:41:
called `Option::unwrap()` on a `None` value
```
I think this is because it first walks the body expression to change any `return` expressions and then walks all tail expressions, resulting in the `return num` being changed twice since it is both a `return` and in tail position. This can also happen when a `match` is in tail position and `return` is used in a branch for example. Not really sure how big of an issue this is in practice though since this seems to be the only case that is impacted and can be reduced to just `num` instead of `return num`.
This also occurs with the `unwrap_result_return_type` assist but panics with the following instead:
```
thread 'handlers::unwrap_result_return_type::tests::wrap_return_in_tail_position' panicked at /rustc/3223b0b5e8dadda3f76c3fd1a8d6c5addc09599e/library/alloc/src/string.rs:1766:29:
assertion failed: self.is_char_boundary(n)
```
minor : Deunwrap convert_comment_block and desugar_doc_comment
Closes subtask 13 of #15398 . I still don't know a more idiomatic way for the for loops I added, any suggestion would make me happy.
Although it doesn't panic now, further changes to how we recover from incomplete syntax
may cause this assist to panic. To mitigate this a test case has been added.
feat: Bool to enum assist
This adds the `bool_to_enum` assist, which converts the type of boolean local variables, fields, constants and statics to a new `enum` type, making it easier to distinguish the meaning of `true` and `false` by renaming the variants.
Closes#14779
Field shorthand overwritten in promote local to const assist
Currently, running `promote_local_to_const` on the following:
```rust
struct Foo {
bar: usize,
}
fn main() {
let $0bar = 0;
let foo = Foo { bar };
}
```
Results in:
```rust
struct Foo {
bar: usize,
}
fn main() {
const BAR: usize = 0;
let foo = Foo { BAR };
}
```
But instead should be something like:
```rust
struct Foo {
bar: usize,
}
fn main() {
const BAR: usize = 0;
let foo = Foo { bar: BAR };
}
```
Bind unused parameter assistant
This PR introduces a new **Bind unused parameter assistant**.
While we do have a QuickFix from `rustc` (prefixing the parameter with an underscore), it's sometimes more convenient to suppress the warning using the following approach:
```rust
fn some_function(unused: i32) {}
```
->
```rust
fn some_function(unused: i32) {
let _ = unused;
}
```
minor : Deunwrap generate_derive
#15398 subtask 1. Since the editing closure has arms, I did something *experimental* ( in this case just a clever term for bad code ) to bypass creating an `Option` but I am ready to change this.
the "add missing members" assists: implemented substitution of default values of const params
To achieve this, I've made `hir::ConstParamData` store the default values
internal : rewrite DeMorgan assist
fixes#15239 , #15240 . This PR is a rewrite of the DeMorgan assist that essentially rids of all the string manipulation and modifies syntax trees to apply demorgan on a binary expr. The main reason for the rewrite is that I wanted to use `Expr::needs_parens_in` method to see if the expr on which the assist is applied would still need the parens it had once the parent expression's operator had equal precedence with that of the expression. I used `.clone_(subtree|for_update)` left and right and probably more than I should have, so I would also be happy to hear how I could have prevented redundant cloning.
internal: Turn unresolved proc macro expansions into missing expressions
Reduces the amount of type related errors one gets when proc macro expansion is disabled.
Add ExternCrateDecl to HIR
Adding these doesn't really require much design effort as they represent a single import, unlike use trees which are one item that represent 0 or more imports.
We only resolve to this definition when actually resolving on the name or alias of an `extern crate name as alias` item, not usages yet as that requires far more changes that won't lead anywhere without giving it more thought. Nevertheless the changes slightly improve IDE things, an example being hover on the decl showing the merged doc comments for example.
cc https://github.com/rust-lang/rust-analyzer/issues/14079
Added remove unused imports assist
This resolves the most important part of #5131. I needed to make a couple of cosmetic changes to the search infrastructure to do this.
A few open questions:
* Should imports that don't resolve to anything be considered unused? I figured probably not, but it would be a trivial change to make if we want it.
* Is there a cleaner way to make the edits to the use list?
* Is there a cleaner way to get the list of uses that intersect the current selection?
* Is the performance acceptable? When testing this on itself, it takes a good couple seconds to perform the assist.
* Is there a way to hide the rustc diagnostics that overlap with this functionality?
internal: Defer structured snippet rendering to allow escaping snippet bits
Since we know exactly where snippets are, we can transparently escape snippet bits to the exact text edits that need it, and not have to do it for anything other text edits.
Also will eventually fix#11006 once all assists are migrated. This comes as a side-effect of text edits that don't have snippets get marked as having no insert formatting at all.