fix: infer for-loop item type with `IntoIterator` and `Iterator`
Part of #13299
We've been inferring the type of the yielded values in for-loop as `<T as IntoIterator>::Item`. We infer the correct type most of the time when we normalize the projection type, but it turns out not always. We should infer the type as `<<T as IntoIterator>::IntoIter as Iterator>::Item`.
When one specifies `IntoIter` assoc type of `IntoIterator` but not `Item` in generic bounds, we fail to normalize `<T as IntoIterator>::Item` (even though `IntoIter` is defined like so: `type IntoIter: Iterator<Item = Self::Item>` - rustc does *not* normalize projections based on other projection's bound I believe; see [this playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=e88e19385094cb98fadbf647b4c2082e)).
Note that this doesn't fully fix # 13299 - given the following code, chalk can normalize `<I as IntoIterator>::IntoIter` to `S`, but cannot normalize `<S as Iterator>::Item` to `i32`.
```rust
struct S;
impl Iterator for S { type Item = i32; /* ... */ }
fn f<I: IntoIterator<IntoIter = S>>(it: I) {
for elem in it {}
//^^^^{unknown}
}
```
This is because chalk finds multiple answers that satisfy the query `AliasEq(<S as Iterator>::Item = ?X`: `?X = i32` and `?X = <I as IntoIterator>::Item` - which are supposed to be the same type due to the aforementioned bound on `IntoIter` but chalk is unable to figure it out.
Amalgamate file changes for the same file ids in process_changes
When receiving multiple change events for a single file id where the last change is a delete the server panics, as it tries to access the file contents of a deleted file. This occurs due to the VFS changes and the in memory file contents being updated immediately, while `process_changes` processes the events afterwards in sequence which no longer works as it will only observe the final file contents. By folding these events together, we will no longer try to process these intermediate changes, as they aren't relevant anyways.
Potentially fixes https://github.com/rust-lang/rust-analyzer/issues/13236
When receiving multiple change events for a single file id where the
last change is a delete the server panics, as it tries to access the
file contents of a deleted file. This occurs due to the VFS changes and
the in memory file contents being updated immediately, while
`process_changes` processes the events afterwards in sequence which no
longer works as it will only observe the final file contents. By
folding these events together, we will no longer try to process these
intermediate changes, as they aren't relevant anyways.
Potentially fixes https://github.com/rust-lang/rust-analyzer/issues/13236
Feature: Add assist to unwrap tuple declarations
> Implement #12923 for only tuples.
>
> Does not implement unwrapping for structs, as mentioned in the issue.
Add assist to unwrap tuples declarations to separate declarations.
```rust
fn main() {
$0let (foo, bar, baz) = (1.0, "example", String::new())
}
```
becomes:
```rust
fn main() {
let foo = 1.0;
let bar = "example";
let baz = String::new();
}
```
## Changelog
### Feature
- Added assist to unwrap tuple declarations.
feat: type inference for generators
This PR implements basic type inference for generator and yield expressions.
Things not included in this PR:
- Generator upvars and generator witnesses are not implemented. They are only used to determine auto trait impls, so basic type inference should be fine without them, but method resolutions with auto trait bounds may not be resolved correctly.
Open questions:
- I haven't (yet) implemented `HirDisplay` for `TyKind::Generator`, so generator types are just shown as "{{generator}}" (in tests, inlay hints, hovers, etc.), which is not really nice. How should we show them?
- I added moderate amount of stuffs to minicore. I especially didn't want to add `impl<T> Deref for &T` and `impl<T> Deref for &mut T` exclusively for tests for generators; should I move them into the test fixtures or can they be placed in minicore?
cc #4309