Skip to content

Commit 4ca6262

Browse files
Avoid Operand::Copy with &mut T
1 parent a0f06d1 commit 4ca6262

File tree

4 files changed

+15
-10
lines changed

4 files changed

+15
-10
lines changed

src/librustc_mir/shim.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,7 @@ fn build_call_shim<'tcx>(
700700

701701
let rcvr = rcvr_adjustment.map(|rcvr_adjustment| match rcvr_adjustment {
702702
Adjustment::Identity => Operand::Move(rcvr_place()),
703-
Adjustment::Deref => Operand::Copy(tcx.mk_place_deref(rcvr_place())),
703+
Adjustment::Deref => Operand::Move(tcx.mk_place_deref(rcvr_place())), // Can't copy `&mut`
704704
Adjustment::DerefMove => Operand::Move(tcx.mk_place_deref(rcvr_place())),
705705
Adjustment::RefMut => {
706706
// let rcvr = &mut rcvr;

src/librustc_mir/transform/instcombine.rs

+12-7
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
//! Performs various peephole optimizations.
22
33
use crate::transform::{MirPass, MirSource};
4-
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
4+
use rustc_data_structures::fx::FxHashMap;
55
use rustc_index::vec::Idx;
66
use rustc_middle::mir::visit::{MutVisitor, Visitor};
77
use rustc_middle::mir::{
8-
Body, Constant, Local, Location, Operand, Place, PlaceRef, ProjectionElem, Rvalue,
8+
Body, Constant, Local, Location, Mutability, Operand, Place, PlaceRef, ProjectionElem, Rvalue,
99
};
1010
use rustc_middle::ty::{self, TyCtxt};
1111
use std::mem;
@@ -39,7 +39,7 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> {
3939
}
4040

4141
fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) {
42-
if self.optimizations.and_stars.remove(&location) {
42+
if let Some(mtbl) = self.optimizations.and_stars.remove(&location) {
4343
debug!("replacing `&*`: {:?}", rvalue);
4444
let new_place = match rvalue {
4545
Rvalue::Ref(_, _, place) => {
@@ -57,7 +57,10 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> {
5757
}
5858
_ => bug!("Detected `&*` but didn't find `&*`!"),
5959
};
60-
*rvalue = Rvalue::Use(Operand::Copy(new_place))
60+
*rvalue = Rvalue::Use(match mtbl {
61+
Mutability::Mut => Operand::Move(new_place),
62+
Mutability::Not => Operand::Copy(new_place),
63+
});
6164
}
6265

6366
if let Some(constant) = self.optimizations.arrays_lengths.remove(&location) {
@@ -88,8 +91,10 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
8891
if let PlaceRef { local, projection: &[ref proj_base @ .., ProjectionElem::Deref] } =
8992
place.as_ref()
9093
{
91-
if Place::ty_from(local, proj_base, self.body, self.tcx).ty.is_region_ptr() {
92-
self.optimizations.and_stars.insert(location);
94+
// The dereferenced place must have type `&_`.
95+
let ty = Place::ty_from(local, proj_base, self.body, self.tcx).ty;
96+
if let ty::Ref(_, _, mtbl) = ty.kind {
97+
self.optimizations.and_stars.insert(location, mtbl);
9398
}
9499
}
95100
}
@@ -109,6 +114,6 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
109114

110115
#[derive(Default)]
111116
struct OptimizationList<'tcx> {
112-
and_stars: FxHashSet<Location>,
117+
and_stars: FxHashMap<Location, Mutability>,
113118
arrays_lengths: FxHashMap<Location, Constant<'tcx>>,
114119
}

src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.a.Inline.after.mir

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ fn a(_1: &mut [T]) -> &mut [T] {
1515
StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15
1616
StorageLive(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:6
1717
_4 = &mut (*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:6
18-
_3 = _4; // scope 1 at $SRC_DIR/libcore/convert/mod.rs:LL:COL
18+
_3 = move _4; // scope 1 at $SRC_DIR/libcore/convert/mod.rs:LL:COL
1919
_2 = &mut (*_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15
2020
StorageDead(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:14: 3:15
2121
_0 = &mut (*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15

src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.b.Inline.after.mir

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ fn b(_1: &mut std::boxed::Box<T>) -> &mut T {
1818
_4 = &mut (*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:6
1919
StorageLive(_5); // scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL
2020
_5 = &mut (*(*_4)); // scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL
21-
_3 = _5; // scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL
21+
_3 = move _5; // scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL
2222
StorageDead(_5); // scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL
2323
_2 = &mut (*_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15
2424
StorageDead(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:14: 8:15

0 commit comments

Comments
 (0)