fix: use `BoundVar`s from current generic scope
Fixup for #13335, addresses https://github.com/rust-lang/rust-analyzer/pull/13339#issuecomment-1266654607
Before the change in generic parameter order, `BoundVar`s for trait reference didn't change whether you are in an impl's scope or in an associated item's scope. Now that item's generic params come before its parent's, we need to shift their indices when we are in an associated item's scope.
fix: treat enum variants as generic item on their own
Fixup for #13335
It turns out I tried to merge two procedures into one utility function without noticing the incompatibility.
This time I *did* run analysis-stats on the four crates and confirmed it doesn't crash and this patch doesn't cause regression.
internal: change generic parameter order
tl;dr: This PR changes the `Substitution` for trait items and methods like so:
```rust
trait Trait<TP, const CP: usize> { // note the implicit Self as first parameter
type Type<TC, const CC: usize>;
fn f<TC, const CC: usize>() {}
}
impl<TP, const CP: usize> S {
fn f<TC, const CC: usize>() {}
}
```
- before this PR: `[Self, TP, CP, TC, CC]` for each trait item, `[TP, CP, TC, CC]` for `S::f`
- after this PR: `[TC, CC, Self, TP, CP]` for each trait item, `[TC, CC, TP, CP]` for `S::f`
---
This PR "inverts" the generic parameters/arguments of an item and its parent. This is to fulfill [chalk's expectation](d875af0ff1/chalk-solve/src/rust_ir.rs (L498-L502)) on the order of generic arguments in `Substitution`s for generic associated types and it's one step forward for GATs support (hopefully). Although chalk doesn't put any constraint for other items, it feels more natural to get everything aligned than special casing GATs.
One complication is that `TyBuilder` now demands its users to pass in parent's `Substitution` upon construction unless it's obvious that the the item has no parent (e.g. an ADT never has parent). All users *should* already know the parent of the item in question, and without this, it cannot be easily reasoned about whether we're pushing the argument for the item or for its parent.
Some additional notes:
- f8f5a5ea57: This isn't related to the change, but I felt it's nicer.
- 78977cd86c: There's one major change here other than the generic param order: Default arguments are now bound by the same `Binder` as the item in question rather than a `Binder` limited to parameters they can refer to (i.e. arguments that syntactically appear before them). Now that the order of generic parameters is changed, it would be somewhat complicated to make such `Binder`s as before, and the "full" `Binder`s shouldn't be a problem because we already make sure that the default arguments don't refer to the generic arguments after them with `fallback_bound_vars()`.
- 7556f74b16: This is split from 4385d3dcd0 to make it easy to revert if it turns out that the GATs with const generics panic is actually not resolved with this PR. cc #11878#11957
This commit "inverts" the order of generic parameters/arguments of an
item and its parent. This is to fulfill chalk's expectation on the
order of `Substitution` for generic associated types and it's one step
forward for their support (hopefully).
Although chalk doesn't put any constraint on the order of `Substitution`
for other items, it feels natural to get everything aligned rather than
special casing GATs.
One complication is that `TyBuilder` now demands its users to pass in
parent's `Substitution` upon construction unless it's obvious that the
the item has no parent (e.g. an ADT never has parent). All users
*should* already know the parent of the item in question, and without
this, it cannot be easily reasoned about whether we're pushing the
argument for the item or for its parent.
Quick comparison of how this commit changes `Substitution`:
```rust
trait Trait<TP, const CP: usize> {
type Type<TC, const CC: usize> = ();
fn f<TC, const CC: usize>() {}
}
```
- before this commit: `[Self, TP, CP, TC, CC]` for each trait item
- after this commit: `[TC, CC, Self, TP, CP]` for each trait item
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