about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAndy Wang <cbeuw.andy@gmail.com>2023-05-15 12:05:10 +0200
committerAndy Wang <cbeuw.andy@gmail.com>2023-05-15 12:05:10 +0200
commitc3ab4f28d37c9577dc401a08a72f82b752d32e53 (patch)
tree5f1cec1803480a5ae840e48ea5a36cf73ce4b16a
parent0bcfd2d96efe7a2cb5205c3af1b9eea17423fe65 (diff)
downloadrust-c3ab4f28d37c9577dc401a08a72f82b752d32e53.tar.gz
rust-c3ab4f28d37c9577dc401a08a72f82b752d32e53.zip
Add CopyForDeref to custom MIR
-rw-r--r--compiler/rustc_mir_build/src/build/custom/parse/instruction.rs1
-rw-r--r--library/core/src/intrinsics/mir.rs1
-rw-r--r--tests/mir-opt/building/custom/projections.copy_for_deref.built.after.mir12
-rw-r--r--tests/mir-opt/building/custom/projections.rs16
4 files changed, 30 insertions, 0 deletions
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<T>(local: T));
 define!("mir_deinit", fn Deinit<T>(place: T));
 define!("mir_checked", fn Checked<T>(binop: T) -> (T, bool));
 define!("mir_len", fn Len<T>(place: T) -> usize);
+define!("mir_copy_for_deref", fn CopyForDeref<T>(place: T) -> T);
 define!("mir_retag", fn Retag<T>(place: T));
 define!("mir_move", fn Move<T>(place: T) -> T);
 define!("mir_static", fn Static<T>(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);
 }