diff --git a/compiler/rustc_mir_transform/src/deref_separator.rs b/compiler/rustc_mir_transform/src/deref_separator.rs index 5e3c0d2cc5ba..c6efe79caafb 100644 --- a/compiler/rustc_mir_transform/src/deref_separator.rs +++ b/compiler/rustc_mir_transform/src/deref_separator.rs @@ -11,41 +11,46 @@ 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))) => { - if borrow_knd == (BorrowKind::Mut { allow_two_phase_borrow: false }) { - for (idx, (p_ref, p_elem)) in place.iter_projections().enumerate() { - if p_elem == ProjectionElem::Deref { - // The type that we are derefing - let ty = p_ref.ty(local_decl, tcx).ty; - let temp = patch.new_temp(ty, stmt.source_info.span); + 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 + let ty = p_ref.ty(local_decl, tcx).ty; + let temp = patch.new_temp(ty, stmt.source_info.span); - // Because we are assigning this right before original statement - // we are using index i of statement - let loc = Location { block: block, statement_index: i }; - patch.add_statement(loc, StatementKind::StorageLive(temp)); + // Because we are assigning this right before original statement + // we are using index i of statement + let loc = Location { block: block, statement_index: i }; + 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); - patch.add_assign( - loc, - Place::from(temp), - Rvalue::Use(Operand::Move(deref_place)), - ); + // 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); + patch.add_assign( + loc, + Place::from(temp), + Rvalue::Use(Operand::Move(deref_place)), + ); - // We are creating a place by using our temp value's location - // and copying derefed values we need to it - let temp_place = - Place::from(temp).project_deeper(&place.projection[idx..], tcx); - patch.add_assign( - loc, + // 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 = + Place::from(temp).project_deeper(&place.projection[idx..], tcx); + patch.add_assign( + loc, + og_place, + Rvalue::Ref(region, borrow_knd, temp_place), + ); + + let new_stmt = Statement { + source_info: stmt.source_info, + kind: StatementKind::Assign(Box::new(( og_place, Rvalue::Ref(region, borrow_knd, temp_place), - ); - // We have to delete the original statement since we just - // replaced it - stmt.make_nop(); - } + ))), + }; + // Replace current statement with newly created one + *stmt = new_stmt; } } } diff --git a/src/test/mir-opt/derefer_test.main.Derefer.diff b/src/test/mir-opt/derefer_test.main.Derefer.diff index 39a364702d00..018049519cf3 100644 --- a/src/test/mir-opt/derefer_test.main.Derefer.diff +++ b/src/test/mir-opt/derefer_test.main.Derefer.diff @@ -38,13 +38,13 @@ + StorageLive(_6); // scope 2 at $DIR/derefer_test.rs:5:13: 5:26 + _6 = move (_2.1: &mut (i32, i32)); // scope 2 at $DIR/derefer_test.rs:5:13: 5:26 + _4 = &mut ((*_6).0: i32); // scope 2 at $DIR/derefer_test.rs:5:13: 5:26 -+ nop; // scope 2 at $DIR/derefer_test.rs:5:13: 5:26 ++ _4 = &mut ((*_6).0: i32); // scope 2 at $DIR/derefer_test.rs:5:13: 5:26 StorageLive(_5); // scope 3 at $DIR/derefer_test.rs:6:9: 6:10 - _5 = &mut ((*(_2.1: &mut (i32, i32))).1: i32); // scope 3 at $DIR/derefer_test.rs:6:13: 6:26 + StorageLive(_7); // scope 3 at $DIR/derefer_test.rs:6:13: 6:26 + _7 = move (_2.1: &mut (i32, i32)); // scope 3 at $DIR/derefer_test.rs:6:13: 6:26 + _5 = &mut ((*_7).1: i32); // scope 3 at $DIR/derefer_test.rs:6:13: 6:26 -+ nop; // scope 3 at $DIR/derefer_test.rs:6:13: 6:26 ++ _5 = &mut ((*_7).1: i32); // scope 3 at $DIR/derefer_test.rs:6:13: 6:26 _0 = const (); // scope 0 at $DIR/derefer_test.rs:2:11: 7:2 StorageDead(_5); // scope 3 at $DIR/derefer_test.rs:7:1: 7:2 StorageDead(_4); // scope 2 at $DIR/derefer_test.rs:7:1: 7:2 diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir index ba19a8472339..e9c02cf2c676 100644 --- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir @@ -6,13 +6,9 @@ fn a(_1: &mut [T]) -> &mut [T] { let mut _2: &mut [T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 let mut _3: &mut [T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 let mut _4: &mut [T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 - let mut _5: &mut [T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 - let mut _6: &mut [T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 scope 1 (inlined <[T] as AsMut<[T]>>::as_mut) { // at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 debug self => _4; // in scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - let mut _7: &mut [T]; // in scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - let mut _8: &mut [T]; // in scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - let mut _9: &mut [T]; // in scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + let mut _5: &mut [T]; // in scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL } bb0: { @@ -20,21 +16,13 @@ fn a(_1: &mut [T]) -> &mut [T] { StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 StorageLive(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 _4 = &mut (*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 - StorageLive(_7); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - StorageLive(_8); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - _8 = move _4; // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - _7 = &mut (*_8); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - StorageLive(_9); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - _9 = move _7; // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - _3 = &mut (*_9); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - StorageDead(_7); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - StorageLive(_5); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 - _5 = move _3; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 - _2 = &mut (*_5); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 + StorageLive(_5); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + _5 = &mut (*_4); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + _3 = &mut (*_5); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + StorageDead(_5); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + _2 = &mut (*_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 StorageDead(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:14: 3:15 - StorageLive(_6); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 - _6 = move _2; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 - _0 = &mut (*_6); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 + _0 = &mut (*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 StorageDead(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:4:1: 4:2 StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:4:1: 4:2 return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:4:2: 4:2 diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir index bfcdccf67377..76a83972c65f 100644 --- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir @@ -6,16 +6,11 @@ fn b(_1: &mut Box) -> &mut T { let mut _2: &mut T; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15 let mut _3: &mut T; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15 let mut _4: &mut std::boxed::Box; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15 - let mut _5: &mut T; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15 - let mut _6: &mut T; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15 scope 1 (inlined as AsMut>::as_mut) { // at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15 debug self => _4; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - let mut _7: &mut T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - let mut _8: &mut T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - let mut _9: &mut std::boxed::Box; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - let mut _10: std::boxed::Box; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - let mut _11: &mut T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - let mut _12: &mut T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _5: &mut T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _6: &mut T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _7: std::boxed::Box; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL } bb0: { @@ -23,29 +18,19 @@ fn b(_1: &mut Box) -> &mut T { StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15 StorageLive(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15 _4 = &mut (*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15 + StorageLive(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + StorageLive(_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL StorageLive(_7); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - StorageLive(_8); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - StorageLive(_9); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _9 = move _4; // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _8 = &mut (*(*_9)); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - StorageLive(_10); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _10 = move (*_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _8 = &mut (*_10); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - StorageLive(_11); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _11 = move _8; // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _7 = &mut (*_11); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - StorageLive(_12); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _12 = move _7; // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _3 = &mut (*_12); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - StorageDead(_8); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - StorageDead(_7); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - StorageLive(_5); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15 - _5 = move _3; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15 - _2 = &mut (*_5); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15 + _7 = move (*_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _6 = &mut (*_7); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _6 = &mut (*_7); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _5 = &mut (*_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _3 = &mut (*_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + StorageDead(_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + StorageDead(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _2 = &mut (*_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15 StorageDead(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:14: 8:15 - StorageLive(_6); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15 - _6 = move _2; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15 - _0 = &mut (*_6); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15 + _0 = &mut (*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15 StorageDead(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:9:1: 9:2 StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:9:1: 9:2 return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:9:2: 9:2 diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir index 422bf748d9ff..433458ed924b 100644 --- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir @@ -7,13 +7,17 @@ fn d(_1: &Box) -> &T { let mut _3: &std::boxed::Box; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15 scope 1 (inlined as AsRef>::as_ref) { // at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15 debug self => _3; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _4: std::boxed::Box; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL } bb0: { StorageLive(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15 StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15 _3 = &(*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15 - _2 = &(*(*_3)); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + StorageLive(_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _4 = move (*_3); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _2 = &(*_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _2 = &(*_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL _0 = &(*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15 StorageDead(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:14: 18:15 StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:19:1: 19:2 diff --git a/src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff index 6832d9eafc9a..06216efcec04 100644 --- a/src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff @@ -5,7 +5,6 @@ let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:48:9: 48:9 - let _1: &mut u32; // in scope 0 at $DIR/simplify-locals.rs:50:14: 50:20 - let mut _2: *mut u32; // in scope 0 at $DIR/simplify-locals.rs:50:19: 50:20 -- let mut _3: *mut u32; // in scope 0 at $DIR/simplify-locals.rs:50:14: 50:20 scope 1 { } @@ -13,9 +12,7 @@ - StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:50:5: 50:22 - StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:50:19: 50:20 - _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify-locals.rs:50:19: 50:20 -- StorageLive(_3); // scope 1 at $DIR/simplify-locals.rs:50:14: 50:20 -- _3 = move _2; // scope 1 at $DIR/simplify-locals.rs:50:14: 50:20 -- _1 = &mut (*_3); // scope 1 at $DIR/simplify-locals.rs:50:14: 50:20 +- _1 = &mut (*_2); // scope 1 at $DIR/simplify-locals.rs:50:14: 50:20 - StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:50:22: 50:23 - StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:50:22: 50:23 return; // scope 0 at $DIR/simplify-locals.rs:51:2: 51:2 diff --git a/src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff index bbafb8d45f60..ee9d2934afd4 100644 --- a/src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff @@ -6,7 +6,6 @@ - let _1: u32; // in scope 0 at $DIR/simplify-locals.rs:56:14: 56:21 - let mut _2: &mut u32; // in scope 0 at $DIR/simplify-locals.rs:56:15: 56:21 - let mut _3: *mut u32; // in scope 0 at $DIR/simplify-locals.rs:56:20: 56:21 -- let mut _4: *mut u32; // in scope 0 at $DIR/simplify-locals.rs:56:15: 56:21 scope 1 { } @@ -15,9 +14,7 @@ - StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:56:15: 56:21 - StorageLive(_3); // scope 1 at $DIR/simplify-locals.rs:56:20: 56:21 - _3 = &/*tls*/ mut X; // scope 1 at $DIR/simplify-locals.rs:56:20: 56:21 -- StorageLive(_4); // scope 1 at $DIR/simplify-locals.rs:56:15: 56:21 -- _4 = move _3; // scope 1 at $DIR/simplify-locals.rs:56:15: 56:21 -- _2 = &mut (*_4); // scope 1 at $DIR/simplify-locals.rs:56:15: 56:21 +- _2 = &mut (*_3); // scope 1 at $DIR/simplify-locals.rs:56:15: 56:21 - _1 = (*_2); // scope 1 at $DIR/simplify-locals.rs:56:14: 56:21 - StorageDead(_3); // scope 0 at $DIR/simplify-locals.rs:56:23: 56:24 - StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:56:23: 56:24 diff --git a/src/test/run-make/const_fn_mir/dump.mir b/src/test/run-make/const_fn_mir/dump.mir index f02bccc4b2da..4e8936905c44 100644 --- a/src/test/run-make/const_fn_mir/dump.mir +++ b/src/test/run-make/const_fn_mir/dump.mir @@ -23,6 +23,10 @@ fn foo() -> i32 { _0 = move (_1.0: i32); // scope 0 at main.rs:5:5: 5:10 return; // scope 0 at main.rs:6:2: 6:2 } + + bb2 (cleanup): { + resume; // scope 0 at main.rs:4:1: 6:2 + } } fn main() -> () {