| Age | Commit message (Collapse) | Author | Lines |
|
BitVector is much more space efficient.
|
|
|
|
|
|
|
|
|
|
Fixes #31504
|
|
this makes the the MIR assignment pass complete successfully
|
|
|
|
|
|
The pass removes the unwind branch of each terminator, thus moving the responsibility of handling
the -Z no-landing-pads flag to a small self-contained pass… instead of polluting the translator.
|
|
|
|
|
|
|
|
The structure of the old translator as well as MIR assumed that drop glue cannot possibly panic and
translated the drops accordingly. However, in presence of `Drop::drop` this assumption can be
trivially shown to be untrue. As such, the Rust code like the following would never print number 2:
```rust
struct Droppable(u32);
impl Drop for Droppable {
fn drop(&mut self) {
if self.0 == 1 { panic!("Droppable(1)") } else { println!("{}", self.0) }
}
}
fn main() {
let x = Droppable(2);
let y = Droppable(1);
}
```
While the behaviour is allowed according to the language rules (we allow drops to not run), that’s
a very counter-intuitive behaviour. We fix this in MIR by allowing `Drop` to have a target to take
on divergence and connect the drops in such a way so the leftover drops are executed when some drop
unwinds.
Note, that this commit still does not implement the translator part of changes necessary for the
grand scheme of things to fully work, so the actual observed behaviour does not change yet. Coming
soon™.
See #14875.
|
|
We used to have CallKind only because there was a requirement to have all successors in a
contiguous memory block. Now that the requirement is gone, remove the CallKind and instead just
have the necessary information inline.
Awesome!
|
|
This helps to avoid the unpleasant restriction of being unable to have multiple successors in
non-contiguous block of memory.
|
|
This gets rid of Drop(Free, _) MIR construct by synthesizing a call to language item which
takes care of dropping instead.
|
|
|
|
|
|
Previously it was returning a value, mostly for the two reasons:
* Cloning Lvalue is very cheap most of the time (i.e. when Lvalue is not a Projection);
* There’s users who want &mut lvalue and there’s users who want &lvalue. Returning a value allows
to make either one easier when pattern matching (i.e. Some(ref dest) or Some(ref mut dest)).
However, I’m now convinced this is an invalid approach. Namely the users which want a mutable
reference may modify the Lvalue in-place, but the changes won’t be reflected in the final MIR,
since the Lvalue modified is merely a clone.
Instead, we have two accessors `destination` and `destination_mut` which return a reference to the
destination in desired mode.
|
|
This merges two separate Call terminators and uses a separate CallKind sub-enum instead.
A little bit unrelatedly, copying into destination value for a certain kind of invoke, is also
implemented here. See the associated comment in code for various details that arise with this
implementation.
|
|
Unreachable terminator can be contained all within the trans.
|
|
|
|
Diverge should eventually go away
|
|
DivergingCall is different enough from the regular converging Call to warrant the split. This also
inlines CallData struct and creates a new CallTargets enum in order to have a way to differentiate
between calls that do not have an associated cleanup block.
Note, that this patch still does not produce DivergingCall terminator anywhere. Look for that in
the next patches.
|
|
|
|
This is done mostly so that we can refer to MIR types in csearch and other metadata related area.
|
|
|
|
For now, this pass does some easy transformations, like eliminating
empty blocks that just jump to another block, some trivial
conversion of If terminators into Gotos and removal of dead blocks.
|