Skip to content

Commit 5c1cb5b

Browse files
committed
Turn projections into copies in CopyProp.
1 parent 3de7d7f commit 5c1cb5b

File tree

4 files changed

+68
-3
lines changed

4 files changed

+68
-3
lines changed

compiler/rustc_mir_transform/src/copy_prop.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,8 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
153153

154154
fn visit_operand(&mut self, operand: &mut Operand<'tcx>, loc: Location) {
155155
if let Operand::Move(place) = *operand
156-
&& let Some(local) = place.as_local()
157-
&& !self.fully_moved.contains(local)
156+
&& !place.has_deref()
157+
&& !self.fully_moved.contains(place.local)
158158
{
159159
*operand = Operand::Copy(place);
160160
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
- // MIR for `f` before CopyProp
2+
+ // MIR for `f` after CopyProp
3+
4+
fn f(_1: Foo) -> bool {
5+
let mut _0: bool; // return place in scope 0 at $DIR/move_projection.rs:+0:17: +0:21
6+
let mut _2: Foo; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
7+
let mut _3: u8; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
8+
9+
bb0: {
10+
- _2 = _1; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
11+
- _3 = move (_2.0: u8); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
12+
- _0 = opaque::<Foo>(move _1) -> bb1; // scope 0 at $DIR/move_projection.rs:+6:13: +6:44
13+
+ _3 = (_1.0: u8); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
14+
+ _0 = opaque::<Foo>(_1) -> bb1; // scope 0 at $DIR/move_projection.rs:+6:13: +6:44
15+
// mir::Constant
16+
// + span: $DIR/move_projection.rs:19:28: 19:34
17+
// + literal: Const { ty: fn(Foo) -> bool {opaque::<Foo>}, val: Value(<ZST>) }
18+
}
19+
20+
bb1: {
21+
_0 = opaque::<u8>(move _3) -> bb2; // scope 0 at $DIR/move_projection.rs:+9:13: +9:44
22+
// mir::Constant
23+
// + span: $DIR/move_projection.rs:22:28: 22:34
24+
// + literal: Const { ty: fn(u8) -> bool {opaque::<u8>}, val: Value(<ZST>) }
25+
}
26+
27+
bb2: {
28+
return; // scope 0 at $DIR/move_projection.rs:+12:13: +12:21
29+
}
30+
}
31+
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// unit-test: CopyProp
2+
3+
#![feature(custom_mir, core_intrinsics)]
4+
#![allow(unused_assignments)]
5+
extern crate core;
6+
use core::intrinsics::mir::*;
7+
8+
fn opaque(_: impl Sized) -> bool { true }
9+
10+
struct Foo(u8);
11+
12+
#[custom_mir(dialect = "analysis", phase = "post-cleanup")]
13+
fn f(a: Foo) -> bool {
14+
mir!(
15+
{
16+
let b = a;
17+
// This is a move out of a copy, so must become a copy of `a.0`.
18+
let c = Move(b.0);
19+
Call(RET, bb1, opaque(Move(a)))
20+
}
21+
bb1 = {
22+
Call(RET, ret, opaque(Move(c)))
23+
}
24+
ret = {
25+
Return()
26+
}
27+
)
28+
}
29+
30+
fn main() {
31+
assert!(f(Foo(0)));
32+
}
33+
34+
// EMIT_MIR move_projection.f.CopyProp.diff

tests/mir-opt/simple_option_map_e2e.ezmap.PreCodegen.after.mir

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ fn ezmap(_1: Option<i32>) -> Option<i32> {
3737
}
3838

3939
bb3: {
40-
_4 = move ((_1 as Some).0: i32); // scope 1 at $DIR/simple_option_map_e2e.rs:7:14: 7:15
40+
_4 = ((_1 as Some).0: i32); // scope 1 at $DIR/simple_option_map_e2e.rs:7:14: 7:15
4141
StorageLive(_5); // scope 2 at $DIR/simple_option_map_e2e.rs:7:25: 7:29
4242
StorageLive(_6); // scope 2 at $DIR/simple_option_map_e2e.rs:7:25: 7:29
4343
_6 = (move _4,); // scope 2 at $DIR/simple_option_map_e2e.rs:7:25: 7:29

0 commit comments

Comments
 (0)