Clean up and add tests for slice drop shims
Adds a test for the MIR generated by `real_drop_in_place::<[T]>`. Also slightly reduces the number of statements and locals used in the shim.
r? @RalfJung
Remove -Z borrowck=compare flag
This is the start of the work that needs to be done on #59193. It just removes the flag and updates
the tests.
r? @matthewjasper
Multi-variant layouts for generators
This allows generators to overlap fields using variants, but doesn't do any such overlapping yet. It creates one variant for every state of the generator (unresumed, returned, panicked, plus one for every yield), and puts every stored local in each of the yield-point variants.
Required for optimizing generator layouts (#52924).
There was quite a lot of refactoring needed for this change. I've done my best in later commits to eliminate assumptions in the code that only certain kinds of types are multi-variant, and to centralize knowledge of the inner mechanics of generators in as few places as possible.
This change also emits debuginfo about the fields contained in each variant, as well as preserving debuginfo about stored locals while running in the generator.
Also, fixes#59972.
Future work:
- Use this change for an optimization pass that actually overlaps locals within the generator struct (#52924)
- In the type layout fields, don't include locals that are uninitialized for a particular variant, so miri and UB sanitizers can check our memory (see https://github.com/rust-lang/rust/issues/59972#issuecomment-483058172)
- Preserve debuginfo scopes across generator yield points
Cleanup the MIR visitor
* Remove useless `BasicBlock` parameters on methods with `Location`s.
* Prefer `visit_terminator_kind` to `visit_terminator`.
* Remove `Region` from PlaceContexts. `visit_rvalue` should be used when the region is important.
* Remove unused visitor methods.
Use a valid name for graphviz graphs
Hiridification has broken graphviz output because `HirId` has a more complex display implemetation than `NodeId`. Since the id was just used to generate a distinct identifier, we just pull out the various constituent indexed.
This commit makes two changes - separating the `NodeId` that identifies
an enum variant from the `NodeId` that identifies the variant's
constructor; and no longer creating a `NodeId` for `Struct`-style enum
variants and structs.
Separation of the variant id and variant constructor id will allow the
rest of RFC 2008 to be implemented by lowering the visibility of the
variant's constructor without lowering the visbility of the variant
itself.
No longer creating a `NodeId` for `Struct`-style enum variants and
structs mostly simplifies logic as previously this `NodeId` wasn't used.
There were various cases where the `NodeId` wouldn't be used unless
there was an unit or tuple struct or enum variant but not all uses of
this `NodeId` had that condition, by removing this `NodeId`, this must
be explicitly dealt with. This change mostly applied cleanly, but there
were one or two cases in name resolution and one case in type check
where the existing logic required a id for `Struct`-style enum variants
and structs.
Fixes for the generator transform
* Moves cleanup annotations in pretty printed MIR so that they can be tested
* Correctly determines which drops are in cleanup blocks when elaborating generator drops
* Use the correct state for poisoning a generator
Closes#58892
Fix ICE in MIR pretty printing
A `Def::Variant` should be considered as a function in mir pretty
printing. Each variant has a constructor that we must print.
Given the following enum definition:
```rust
pub enum TestMe {
X(usize),
}
```
We will need to generate a constructor for the variant `X` with a
signature that looks something like the following:
```
fn TestMe::X(_1: usize) -> TestMe;
```
Fixes: #59021
A `Def::Variant` should be considered as a function in mir pretty
printing. Each variant has a constructor that we must print.
Given the following enum definition:
```
pub enum TestMe {
X(usize),
}
```
We will need to generate a constructor for the variant `X` with a
signature that looks something like the following:
```
fn TestMe::X(_1: usize) -> TestMe;
```
[NLL] Remove `LiveVar`
The `LiveVar` type (and related) made it harder to reason about the code. It seemed as an abstraction that didn't bring any useful concept to the reader (when transitioning from the RFC theory to the actual implementation code).
It achieved a compactness in the vectors storing the def/use/drop information that was related only to the `LocalUseMap`. This PR went in the other direction and favored time over memory (but this decision can be easily reverted to the other side without reintroducing `LiveVar`).
What this PR aims at is to clarify that there's no significant transformation between the MIR `Local` and the `LiveVar` (now refactored as `live_locals: Vec<Local>`): we're just filtering (not mapping) the entire group of `Local`s into a meaningful subset that we should perform the liveness analysis on.
As a side note, there is no guarantee that the liveness analysis is performed only on (what the code calls) "live" variables, if the NLL facts are requested it will be performed on *any* variable so there can't be any assumptions on that regard. (Still, this PR didn't change the general naming convention to reduce the number of changes here and streamline the review process).
**Acceptance criteria:** This PR attempts to do only a minor refactoring and not to change the logic so it can't have any performance impact, particularly, it can't lose any of the significant performance improvement achieved in the great work done in https://github.com/rust-lang/rust/pull/52115.
r? @nikomatsakis
With `NllLivenessMap` and `LiveVar` removed, the `IdentityMap` (remaining
structure implementing the `LiveVariableMap` trait) loses its meaning.
Specialize the `LiveVarSet` to a `BitSet<Local>` removing the `V` and related
parameters. The `LiveVarSet<V>` was only being used as `LiveVarSet<Local>` so
this commit doesn't bring any change to the logic, it just removes an unused
parameter (that without `LiveVar` now, it couldn't have been specialized to
anything but `Local`).
Fix ICE and invalid filenames in MIR printing code
* Don't panic when printing MIR for associated constants
* Don't use `<` and `>` in filenames, since they aren't allowed on Windows.
r? @eddyb
cc @RalfJung
Make -Zdump-mir dump shims
Fixes https://github.com/rust-lang/rust/issues/53532 by (a) making the MIR shim generation use the MIR pass infrastructure, and (b) fixing said infrastructure to handle the fallout.
Cc @eddyb @oli-obk
Make `intern_lazy_const` actually intern its argument.
Currently it just unconditionally allocates it in the arena.
For a "Clean Check" build of the the `packed-simd` benchmark, this
change reduces both the `max-rss` and `faults` counts by 59%; it
slightly (~3%) increases the instruction counts but the `wall-time` is
unchanged.
For the same builds of a few other benchmarks, `max-rss` and `faults`
drop by 1--5%, but instruction counts and `wall-time` changes are in the
noise.
Fixes#57432, fixes#57829.