Rollup merge of #95857 - ouz-a:mir-opt, r=oli-obk
Allow multiple derefs to be splitted in deref_separator Previously in #95649 only a single deref within projection was supported and multiple derefs caused a bunch of issues, this PR fixes those issues. ```@oli-obk``` helped a ton again ❤️
This commit is contained in:
commit
78fc931355
3 changed files with 117 additions and 8 deletions
|
@ -11,6 +11,8 @@ pub fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
|||
for (i, stmt) in data.statements.iter_mut().enumerate() {
|
||||
match stmt.kind {
|
||||
StatementKind::Assign(box (og_place, Rvalue::Ref(region, borrow_knd, place))) => {
|
||||
let mut place_local = place.local;
|
||||
let mut last_len = 0;
|
||||
for (idx, (p_ref, p_elem)) in place.iter_projections().enumerate() {
|
||||
if p_elem == ProjectionElem::Deref && !p_ref.projection.is_empty() {
|
||||
// The type that we are derefing.
|
||||
|
@ -23,15 +25,18 @@ pub fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
|||
patch.add_statement(loc, StatementKind::StorageLive(temp));
|
||||
|
||||
// We are adding current p_ref's projections to our
|
||||
// temp value.
|
||||
let deref_place =
|
||||
Place::from(p_ref.local).project_deeper(p_ref.projection, tcx);
|
||||
// temp value, excluding projections we already covered.
|
||||
let deref_place = Place::from(place_local)
|
||||
.project_deeper(&p_ref.projection[last_len..], tcx);
|
||||
patch.add_assign(
|
||||
loc,
|
||||
Place::from(temp),
|
||||
Rvalue::Use(Operand::Move(deref_place)),
|
||||
);
|
||||
|
||||
place_local = temp;
|
||||
last_len = p_ref.projection.len();
|
||||
|
||||
// We are creating a place by using our temp value's location
|
||||
// and copying derefed values which we need to create new statement.
|
||||
let temp_place =
|
||||
|
@ -50,11 +55,6 @@ pub fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
|||
// Since our job with the temp is done it should be gone
|
||||
let loc = Location { block: block, statement_index: i + 1 };
|
||||
patch.add_statement(loc, StatementKind::StorageDead(temp));
|
||||
|
||||
// As all projections are off the base projection, if there are
|
||||
// multiple derefs in the middle of projection, it might cause
|
||||
// unsoundness, to not let that happen we break the loop.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
100
src/test/mir-opt/derefer_test_multiple.main.Derefer.diff
Normal file
100
src/test/mir-opt/derefer_test_multiple.main.Derefer.diff
Normal file
|
@ -0,0 +1,100 @@
|
|||
- // MIR for `main` before Derefer
|
||||
+ // MIR for `main` after Derefer
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/derefer_test_multiple.rs:2:12: 2:12
|
||||
let mut _1: (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:3:9: 3:14
|
||||
let mut _3: &mut (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:4:22: 4:28
|
||||
let mut _5: &mut (i32, &mut (i32, i32)); // in scope 0 at $DIR/derefer_test_multiple.rs:5:22: 5:28
|
||||
let mut _7: &mut (i32, &mut (i32, &mut (i32, i32))); // in scope 0 at $DIR/derefer_test_multiple.rs:6:22: 6:28
|
||||
+ let mut _10: &mut (i32, &mut (i32, &mut (i32, i32))); // in scope 0 at $DIR/derefer_test_multiple.rs:7:13: 7:30
|
||||
+ let mut _11: &mut (i32, &mut (i32, i32)); // in scope 0 at $DIR/derefer_test_multiple.rs:7:13: 7:30
|
||||
+ let mut _12: &mut (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:7:13: 7:30
|
||||
+ let mut _13: &mut (i32, &mut (i32, &mut (i32, i32))); // in scope 0 at $DIR/derefer_test_multiple.rs:8:13: 8:30
|
||||
+ let mut _14: &mut (i32, &mut (i32, i32)); // in scope 0 at $DIR/derefer_test_multiple.rs:8:13: 8:30
|
||||
+ let mut _15: &mut (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:8:13: 8:30
|
||||
scope 1 {
|
||||
debug a => _1; // in scope 1 at $DIR/derefer_test_multiple.rs:3:9: 3:14
|
||||
let mut _2: (i32, &mut (i32, i32)); // in scope 1 at $DIR/derefer_test_multiple.rs:4:9: 4:14
|
||||
scope 2 {
|
||||
debug b => _2; // in scope 2 at $DIR/derefer_test_multiple.rs:4:9: 4:14
|
||||
let mut _4: (i32, &mut (i32, &mut (i32, i32))); // in scope 2 at $DIR/derefer_test_multiple.rs:5:9: 5:14
|
||||
scope 3 {
|
||||
debug c => _4; // in scope 3 at $DIR/derefer_test_multiple.rs:5:9: 5:14
|
||||
let mut _6: (i32, &mut (i32, &mut (i32, &mut (i32, i32)))); // in scope 3 at $DIR/derefer_test_multiple.rs:6:9: 6:14
|
||||
scope 4 {
|
||||
debug d => _6; // in scope 4 at $DIR/derefer_test_multiple.rs:6:9: 6:14
|
||||
let _8: &mut i32; // in scope 4 at $DIR/derefer_test_multiple.rs:7:9: 7:10
|
||||
scope 5 {
|
||||
debug x => _8; // in scope 5 at $DIR/derefer_test_multiple.rs:7:9: 7:10
|
||||
let _9: &mut i32; // in scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10
|
||||
scope 6 {
|
||||
debug y => _9; // in scope 6 at $DIR/derefer_test_multiple.rs:8:9: 8:10
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1); // scope 0 at $DIR/derefer_test_multiple.rs:3:9: 3:14
|
||||
(_1.0: i32) = const 42_i32; // scope 0 at $DIR/derefer_test_multiple.rs:3:17: 3:25
|
||||
(_1.1: i32) = const 43_i32; // scope 0 at $DIR/derefer_test_multiple.rs:3:17: 3:25
|
||||
StorageLive(_2); // scope 1 at $DIR/derefer_test_multiple.rs:4:9: 4:14
|
||||
StorageLive(_3); // scope 1 at $DIR/derefer_test_multiple.rs:4:22: 4:28
|
||||
_3 = &mut _1; // scope 1 at $DIR/derefer_test_multiple.rs:4:22: 4:28
|
||||
(_2.0: i32) = const 99_i32; // scope 1 at $DIR/derefer_test_multiple.rs:4:17: 4:29
|
||||
(_2.1: &mut (i32, i32)) = move _3; // scope 1 at $DIR/derefer_test_multiple.rs:4:17: 4:29
|
||||
StorageDead(_3); // scope 1 at $DIR/derefer_test_multiple.rs:4:28: 4:29
|
||||
StorageLive(_4); // scope 2 at $DIR/derefer_test_multiple.rs:5:9: 5:14
|
||||
StorageLive(_5); // scope 2 at $DIR/derefer_test_multiple.rs:5:22: 5:28
|
||||
_5 = &mut _2; // scope 2 at $DIR/derefer_test_multiple.rs:5:22: 5:28
|
||||
(_4.0: i32) = const 11_i32; // scope 2 at $DIR/derefer_test_multiple.rs:5:17: 5:29
|
||||
(_4.1: &mut (i32, &mut (i32, i32))) = move _5; // scope 2 at $DIR/derefer_test_multiple.rs:5:17: 5:29
|
||||
StorageDead(_5); // scope 2 at $DIR/derefer_test_multiple.rs:5:28: 5:29
|
||||
StorageLive(_6); // scope 3 at $DIR/derefer_test_multiple.rs:6:9: 6:14
|
||||
StorageLive(_7); // scope 3 at $DIR/derefer_test_multiple.rs:6:22: 6:28
|
||||
_7 = &mut _4; // scope 3 at $DIR/derefer_test_multiple.rs:6:22: 6:28
|
||||
(_6.0: i32) = const 13_i32; // scope 3 at $DIR/derefer_test_multiple.rs:6:17: 6:29
|
||||
(_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))) = move _7; // scope 3 at $DIR/derefer_test_multiple.rs:6:17: 6:29
|
||||
StorageDead(_7); // scope 3 at $DIR/derefer_test_multiple.rs:6:28: 6:29
|
||||
StorageLive(_8); // scope 4 at $DIR/derefer_test_multiple.rs:7:9: 7:10
|
||||
- _8 = &mut ((*((*((*(_6.1: &mut (i32, &mut (i32, &mut (i32, i32))))).1: &mut (i32, &mut (i32, i32)))).1: &mut (i32, i32))).1: i32); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
|
||||
+ StorageLive(_10); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
|
||||
+ _10 = move (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
|
||||
+ StorageLive(_11); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
|
||||
+ _11 = move ((*_10).1: &mut (i32, &mut (i32, i32))); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
|
||||
+ StorageLive(_12); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
|
||||
+ _12 = move ((*_11).1: &mut (i32, i32)); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
|
||||
+ _8 = &mut ((*_12).1: i32); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
|
||||
+ StorageDead(_10); // scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10
|
||||
+ StorageDead(_11); // scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10
|
||||
+ StorageDead(_12); // scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10
|
||||
StorageLive(_9); // scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10
|
||||
- _9 = &mut ((*((*((*(_6.1: &mut (i32, &mut (i32, &mut (i32, i32))))).1: &mut (i32, &mut (i32, i32)))).1: &mut (i32, i32))).1: i32); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
|
||||
+ StorageLive(_13); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
|
||||
+ _13 = move (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
|
||||
+ StorageLive(_14); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
|
||||
+ _14 = move ((*_13).1: &mut (i32, &mut (i32, i32))); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
|
||||
+ StorageLive(_15); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
|
||||
+ _15 = move ((*_14).1: &mut (i32, i32)); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
|
||||
+ _9 = &mut ((*_15).1: i32); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
|
||||
+ StorageDead(_13); // scope 0 at $DIR/derefer_test_multiple.rs:2:12: 9:2
|
||||
+ StorageDead(_14); // scope 0 at $DIR/derefer_test_multiple.rs:2:12: 9:2
|
||||
+ StorageDead(_15); // scope 0 at $DIR/derefer_test_multiple.rs:2:12: 9:2
|
||||
_0 = const (); // scope 0 at $DIR/derefer_test_multiple.rs:2:12: 9:2
|
||||
StorageDead(_9); // scope 5 at $DIR/derefer_test_multiple.rs:9:1: 9:2
|
||||
StorageDead(_8); // scope 4 at $DIR/derefer_test_multiple.rs:9:1: 9:2
|
||||
StorageDead(_6); // scope 3 at $DIR/derefer_test_multiple.rs:9:1: 9:2
|
||||
StorageDead(_4); // scope 2 at $DIR/derefer_test_multiple.rs:9:1: 9:2
|
||||
StorageDead(_2); // scope 1 at $DIR/derefer_test_multiple.rs:9:1: 9:2
|
||||
StorageDead(_1); // scope 0 at $DIR/derefer_test_multiple.rs:9:1: 9:2
|
||||
return; // scope 0 at $DIR/derefer_test_multiple.rs:9:2: 9:2
|
||||
+ }
|
||||
+
|
||||
+ bb1 (cleanup): {
|
||||
+ resume; // scope 0 at $DIR/derefer_test_multiple.rs:2:1: 9:2
|
||||
}
|
||||
}
|
||||
|
9
src/test/mir-opt/derefer_test_multiple.rs
Normal file
9
src/test/mir-opt/derefer_test_multiple.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
// EMIT_MIR derefer_test_multiple.main.Derefer.diff
|
||||
fn main () {
|
||||
let mut a = (42, 43);
|
||||
let mut b = (99, &mut a);
|
||||
let mut c = (11, &mut b);
|
||||
let mut d = (13, &mut c);
|
||||
let x = &mut (*d.1).1.1.1;
|
||||
let y = &mut (*d.1).1.1.1;
|
||||
}
|
Loading…
Add table
Reference in a new issue