Skip to content

Commit eeebb65

Browse files
authored
Rollup merge of #111587 - cbeuw:copy-for-deref, r=oli-obk
Custom MIR: Support `Rvalue::CopyForDeref` r? `@oli-obk` or `@tmiasko` or `@JakobDegen`
2 parents 119b722 + 3d938dd commit eeebb65

File tree

5 files changed

+37
-12
lines changed

5 files changed

+37
-12
lines changed

compiler/rustc_mir_build/src/build/custom/parse/instruction.rs

+1
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
154154
Ok(Rvalue::BinaryOp(BinOp::Offset, Box::new((ptr, offset))))
155155
},
156156
@call("mir_len", args) => Ok(Rvalue::Len(self.parse_place(args[0])?)),
157+
@call("mir_copy_for_deref", args) => Ok(Rvalue::CopyForDeref(self.parse_place(args[0])?)),
157158
ExprKind::Borrow { borrow_kind, arg } => Ok(
158159
Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?)
159160
),

library/core/src/intrinsics/mir.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@
228228
//!
229229
//! - Operands implicitly convert to `Use` rvalues.
230230
//! - `&`, `&mut`, `addr_of!`, and `addr_of_mut!` all work to create their associated rvalue.
231-
//! - [`Discriminant`] and [`Len`] have associated functions.
231+
//! - [`Discriminant`], [`Len`], and [`CopyForDeref`] have associated functions.
232232
//! - Unary and binary operations use their normal Rust syntax - `a * b`, `!c`, etc.
233233
//! - The binary operation `Offset` can be created via [`Offset`].
234234
//! - Checked binary operations are represented by wrapping the associated binop in [`Checked`].
@@ -279,6 +279,7 @@ define!("mir_storage_dead", fn StorageDead<T>(local: T));
279279
define!("mir_deinit", fn Deinit<T>(place: T));
280280
define!("mir_checked", fn Checked<T>(binop: T) -> (T, bool));
281281
define!("mir_len", fn Len<T>(place: T) -> usize);
282+
define!("mir_copy_for_deref", fn CopyForDeref<T>(place: T) -> T);
282283
define!("mir_retag", fn Retag<T>(place: T));
283284
define!("mir_move", fn Move<T>(place: T) -> T);
284285
define!("mir_static", fn Static<T>(s: T) -> &'static T);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// MIR for `copy_for_deref` after built
2+
3+
fn copy_for_deref(_1: (&i32, i32)) -> i32 {
4+
let mut _0: i32; // return place in scope 0 at $DIR/projections.rs:+0:38: +0:41
5+
let mut _2: &i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
6+
7+
bb0: {
8+
_2 = deref_copy (_1.0: &i32); // scope 0 at $DIR/projections.rs:+4:13: +4:37
9+
_0 = (*_2); // scope 0 at $DIR/projections.rs:+5:13: +5:24
10+
return; // scope 0 at $DIR/projections.rs:+6:13: +6:21
11+
}
12+
}

tests/mir-opt/building/custom/projections.rs

+19-6
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,10 @@ fn unions(u: U) -> i32 {
2121
#[custom_mir(dialect = "analysis", phase = "post-cleanup")]
2222
fn tuples(i: (u32, i32)) -> (u32, i32) {
2323
mir!(
24-
// FIXME(JakobDegen): This is necessary because we can't give type hints for `RET`
25-
let temp: (u32, i32);
24+
type RET = (u32, i32);
2625
{
27-
temp.0 = i.0;
28-
temp.1 = i.1;
29-
30-
RET = temp;
26+
RET.0 = i.0;
27+
RET.1 = i.1;
3128
Return()
3229
}
3330
)
@@ -71,6 +68,19 @@ fn simple_index(a: [i32; 10], b: &[i32]) -> i32 {
7168
})
7269
}
7370

71+
// EMIT_MIR projections.copy_for_deref.built.after.mir
72+
#[custom_mir(dialect = "runtime", phase = "initial")]
73+
fn copy_for_deref(x: (&i32, i32)) -> i32 {
74+
mir!(
75+
let temp: &i32;
76+
{
77+
temp = CopyForDeref(x.0);
78+
RET = *temp;
79+
Return()
80+
}
81+
)
82+
}
83+
7484
fn main() {
7585
assert_eq!(unions(U { a: 5 }), 5);
7686
assert_eq!(tuples((5, 6)), (5, 6));
@@ -82,4 +92,7 @@ fn main() {
8292
assert_eq!(o, Some(10));
8393

8494
assert_eq!(simple_index([0; 10], &[0; 10]), 0);
95+
96+
let one = 1;
97+
assert_eq!(copy_for_deref((&one, one)), 1);
8598
}

tests/mir-opt/building/custom/projections.tuples.built.after.mir

+3-5
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22

33
fn tuples(_1: (u32, i32)) -> (u32, i32) {
44
let mut _0: (u32, i32); // return place in scope 0 at $DIR/projections.rs:+0:29: +0:39
5-
let mut _2: (u32, i32); // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
65

76
bb0: {
8-
(_2.0: u32) = (_1.0: u32); // scope 0 at $DIR/projections.rs:+5:13: +5:25
9-
(_2.1: i32) = (_1.1: i32); // scope 0 at $DIR/projections.rs:+6:13: +6:25
10-
_0 = _2; // scope 0 at $DIR/projections.rs:+8:13: +8:23
11-
return; // scope 0 at $DIR/projections.rs:+9:13: +9:21
7+
(_0.0: u32) = (_1.0: u32); // scope 0 at $DIR/projections.rs:+4:13: +4:24
8+
(_0.1: i32) = (_1.1: i32); // scope 0 at $DIR/projections.rs:+5:13: +5:24
9+
return; // scope 0 at $DIR/projections.rs:+6:13: +6:21
1210
}
1311
}

0 commit comments

Comments
 (0)