diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs index 931fe1b2433..b74422708ce 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -154,6 +154,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { Ok(Rvalue::BinaryOp(BinOp::Offset, Box::new((ptr, offset)))) }, @call("mir_len", args) => Ok(Rvalue::Len(self.parse_place(args[0])?)), + @call("mir_copy_for_deref", args) => Ok(Rvalue::CopyForDeref(self.parse_place(args[0])?)), ExprKind::Borrow { borrow_kind, arg } => Ok( Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?) ), diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs index 19f8b944c1f..b1a112849d8 100644 --- a/library/core/src/intrinsics/mir.rs +++ b/library/core/src/intrinsics/mir.rs @@ -279,6 +279,7 @@ define!("mir_storage_dead", fn StorageDead(local: T)); define!("mir_deinit", fn Deinit(place: T)); define!("mir_checked", fn Checked(binop: T) -> (T, bool)); define!("mir_len", fn Len(place: T) -> usize); +define!("mir_copy_for_deref", fn CopyForDeref(place: T) -> T); define!("mir_retag", fn Retag(place: T)); define!("mir_move", fn Move(place: T) -> T); define!("mir_static", fn Static(s: T) -> &'static T); diff --git a/tests/mir-opt/building/custom/projections.copy_for_deref.built.after.mir b/tests/mir-opt/building/custom/projections.copy_for_deref.built.after.mir new file mode 100644 index 00000000000..5233d0489c6 --- /dev/null +++ b/tests/mir-opt/building/custom/projections.copy_for_deref.built.after.mir @@ -0,0 +1,12 @@ +// MIR for `copy_for_deref` after built + +fn copy_for_deref(_1: (&i32, i32)) -> i32 { + let mut _0: i32; // return place in scope 0 at $DIR/projections.rs:+0:38: +0:41 + let mut _2: &i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + _2 = deref_copy (_1.0: &i32); // scope 0 at $DIR/projections.rs:+4:13: +4:37 + _0 = (*_2); // scope 0 at $DIR/projections.rs:+5:13: +5:24 + return; // scope 0 at $DIR/projections.rs:+6:13: +6:21 + } +} diff --git a/tests/mir-opt/building/custom/projections.rs b/tests/mir-opt/building/custom/projections.rs index 5e472e531c7..bd6db0e5c4c 100644 --- a/tests/mir-opt/building/custom/projections.rs +++ b/tests/mir-opt/building/custom/projections.rs @@ -71,6 +71,19 @@ fn simple_index(a: [i32; 10], b: &[i32]) -> i32 { }) } +// EMIT_MIR projections.copy_for_deref.built.after.mir +#[custom_mir(dialect = "runtime", phase = "initial")] +fn copy_for_deref(x: (&i32, i32)) -> i32 { + mir!( + let temp: &i32; + { + temp = CopyForDeref(x.0); + RET = *temp; + Return() + } + ) +} + fn main() { assert_eq!(unions(U { a: 5 }), 5); assert_eq!(tuples((5, 6)), (5, 6)); @@ -82,4 +95,7 @@ fn main() { assert_eq!(o, Some(10)); assert_eq!(simple_index([0; 10], &[0; 10]), 0); + + let one = 1; + assert_eq!(copy_for_deref((&one, one)), 1); }