fix: autocomplete constants inside format strings
Hi! This PR adds autocompletion for constants (including statics) inside format strings and closes#16608.
I'm not sure about adding the `constants` field to the `CompletionContext`. It kinda makes sense, since it's in line with the `locals` field, and this way everything looks a bit cleaner, but at the same time does it really need to be there?
Anyway, let me know if anything should/can be changed. :)
Export `SemanticsImpl` from `ra_ap_hir` crate, since it's already exposed via `Semantics.deref()`
The `SemanticsImpl` type is already de-facto exposed via `<Semantics as Deref>::Target`.
By not being part of the public crate interface it however doesn't get included in the documentation, resulting in a massive blind spot when it comes to `ra_ap_hir`'s type resolution APIs.
Add public function for resolving callable AST exprs to their HIR equivalents
(the PR is motivated by an outside use of the `ra_ap_hir` crate that would benefit from being able to walk a `hir::Function`'s AST, resolving callable exprs within to their HIR equivalents)
Derive `PartialEq`, `Eq` & `Hash` for `hir::Param`
Since `hir::SelfParam`, as well as all members of `hir::Param` already implement `PartialEq`, `Eq` & `Hash` it seems reasonable to also make `hir::Param` implement those.
(the change is motivated by an outside use of the `ra_ap_hir` crate that would benefit from being able to collect params in a `HashSet`)
feature: Add `destructure_struct_binding`
Adds an assist for destructuring a struct in a binding (#8673). I saw that #13997 has been abandoned for a while, so I thought I'd give it a go.
## Example
```rust
let foo = Foo { bar: 1, baz: 2 };
let bar2 = foo.bar;
let baz2 = foo.baz;
let foo2 = foo;
let fizz = Fizz(1, 2);
let buzz = fizz.0;
```
becomes
```rust
let Foo { bar, baz } = Foo { bar: 1, baz: 2 };
let bar2 = bar;
let baz2 = baz;
let foo2 = todo!();
let Fizz(_0, _1) = Fizz(1, 2);
let buzz = _0;
```
More examples in the tests.
## What is included?
- [x] Destructure record, tuple, and unit struct bindings
- [x] Edit field usages
- [x] Non-exhaustive structs in foreign crates and private fields get hidden behind `..`
- [x] Nested bindings
- [x] Carry over `mut` and `ref mut` in nested bindings to fields, i.e. `let Foo { ref mut bar } = ...` becomes `let Foo { bar: Bar { baz: ref mut baz } } = ...`
- [x] Attempt to resolve collisions with other names in the scope
- [x] If the binding is to a reference, field usages are dereferenced if required
- [x] Use shorthand notation if possible
## Known limitations
- `let foo = Foo { bar: 1 }; foo;` currently results in `let Foo { bar } = Foo { bar: 1 }; todo!();` instead of reassembling the struct. This requires user intervention.
- Unused fields are not currently omitted. I thought that this is more ergonomic, as there already is a quick fix action for adding `: _` to unused field patterns.
fix: Goto definition for `index_mut`
Mostly same with #16696.
0ac05c0527/crates/hir-ty/src/infer/mutability.rs (L103-L133)
Thankfully, we are doing similar method resolutions so we can use them like the mentioned PR.
As there are only three `LangItem`s having `Mut` in there names; `FnMut`, `DerefMut` and `IndexMut`, I think that this is the last one 😄
Separate into create and apply edit
Rename usages
Hacky name map
Add more tests
Handle non-exhaustive
Add some more TODOs
Private fields
Use todo
Nesting
Improve rest token generation
Cleanup
Doc -> regular comment
Support mut
Add `to_path_buf()` method for `RelPath`
There seems to be no ergonomic way to obtain a `RelPathBuf` from a corresponding `&RelPath` at the moment, making the latter sort of a dead end.
The `AbsPath` type provides the following:
```rust
impl AbsPath {
// ...
/// Equivalent of [`Path::to_path_buf`] for `AbsPath`.
pub fn to_path_buf(&self) -> AbsPathBuf {
AbsPathBuf::try_from(self.0.to_path_buf()).unwrap()
}
// ...
}
```
So I took the liberty of adding a corresponding equivalent for `RelPath:
```rust
impl RelPath {
// ...
/// Equivalent of [`Path::to_path_buf`] for `RelPath`.
pub fn to_path_buf(&self) -> RelPathBuf {
RelPathBuf::try_from(self.0.to_path_buf()).unwrap()
}
// ...
}
```
(the change is motivated by an outside use of the `ra_ap_paths` crate that would benefit from being able to use `RelPath` and `AbsPath` over `Path`)
fix: Wrong closure kind deduction for closures with predicates
Completes #16472, fixes#16421
The changed closure kind deduction is mostly simlar to `rustc_hir_typeck/src/closure.rs`.
Porting closure sig deduction from it seems possible too and I'm considering doing it with another PR
feat: Add "make tuple" tactic to term search
Follow up to https://github.com/rust-lang/rust-analyzer/pull/16092
Now term search also supports tuples.
```rust
let a: i32 = 1;
let b: f64 = 0.0;
let c: (i32, (f64, i32)) = todo!(); // Finds (a, (b, a))
```
In addition to new tactic that handles tuples I changed how the generics are handled.
Previously it tried all possible options from types we had in scope but now it only tries useful ones that help us directly towards the goal or at least towards calling some other function.
This changes O(2^n) to O(n^2) where n is amount of rounds which in practice allows using types that take generics for multiple rounds (previously limited to 1). Average case that also used to be exponential is now roughly linear.
This means that deeply nested generics also work.
````rust
// Finds all valid combos, including `Some(Some(Some(...)))`
let a: Option<Option<Option<bool>>> = todo!();
````
_Note that although the complexity is smaller allowing more types with generics the search overall slows down considerably. I hope it's fine tho as the autocomplete is disabled by default and for code actions it's not super slow. Might have to tweak the depth hyper parameter tho_
This resulted in a huge increase of results found (benchmarks on `ripgrep` crate):
Before
````
Tail Expr syntactic hits: 149/1692 (8%)
Tail Exprs found: 749/1692 (44%)
Term search avg time: 18ms
```
After
```
Tail Expr syntactic hits: 291/1692 (17%)
Tail Exprs found: 1253/1692 (74%)
Term search avg time: 139ms
````
Most changes are local to term search except some tuple related stuff on `hir::Type`.