about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/custom/parse/instruction.rs22
-rw-r--r--tests/mir-opt/building/custom/aggregate_exprs.adt.built.after.mir16
-rw-r--r--tests/mir-opt/building/custom/aggregate_exprs.array.built.after.mir15
-rw-r--r--tests/mir-opt/building/custom/aggregate_exprs.rs71
-rw-r--r--tests/mir-opt/building/custom/aggregate_exprs.tuple.built.after.mir10
6 files changed, 135 insertions, 1 deletions
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index b16b6616415..a702a6b9ee1 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -1165,7 +1165,7 @@ pub enum AggregateKind<'tcx> {
     Tuple,
 
     /// The second field is the variant index. It's equal to 0 for struct
-    /// and union expressions. The fourth field is
+    /// and union expressions. The last field is the
     /// active field number and is present only for union expressions
     /// -- e.g., for a union expression `SomeUnion { c: .. }`, the
     /// active field index would identity the field `c`
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 5e77f2dc126..adbd37a7cd9 100644
--- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
+++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
@@ -166,6 +166,28 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
                 let cast_kind = mir_cast_kind(source_ty, expr.ty);
                 Ok(Rvalue::Cast(cast_kind, source, expr.ty))
             },
+            ExprKind::Tuple { fields } => Ok(
+                Rvalue::Aggregate(
+                    Box::new(AggregateKind::Tuple),
+                    fields.iter().map(|e| self.parse_operand(*e)).collect::<Result<_, _>>()?
+                )
+            ),
+            ExprKind::Array { fields } => {
+                let elem_ty = expr.ty.builtin_index().expect("ty must be an array");
+                Ok(Rvalue::Aggregate(
+                    Box::new(AggregateKind::Array(elem_ty)),
+                    fields.iter().map(|e| self.parse_operand(*e)).collect::<Result<_, _>>()?
+                ))
+            },
+            ExprKind::Adt(box AdtExpr{ adt_def, variant_index, substs, fields, .. }) => {
+                let is_union = adt_def.is_union();
+                let active_field_index = is_union.then(|| fields[0].name.index());
+
+                Ok(Rvalue::Aggregate(
+                    Box::new(AggregateKind::Adt(adt_def.did(), *variant_index, substs, None, active_field_index)),
+                    fields.iter().map(|f| self.parse_operand(f.expr)).collect::<Result<_, _>>()?
+                ))
+            },
             _ => self.parse_operand(expr_id).map(Rvalue::Use),
         )
     }
diff --git a/tests/mir-opt/building/custom/aggregate_exprs.adt.built.after.mir b/tests/mir-opt/building/custom/aggregate_exprs.adt.built.after.mir
new file mode 100644
index 00000000000..49e8c812c19
--- /dev/null
+++ b/tests/mir-opt/building/custom/aggregate_exprs.adt.built.after.mir
@@ -0,0 +1,16 @@
+// MIR for `adt` after built
+
+fn adt() -> Onion {
+    let mut _0: Onion;                   // return place in scope 0 at $DIR/aggregate_exprs.rs:+0:13: +0:18
+    let mut _1: i32;                     // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+    let mut _2: Foo;                     // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+    let mut _3: Bar;                     // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+    bb0: {
+        _1 = const 1_i32;                // scope 0 at $DIR/aggregate_exprs.rs:+6:13: +6:20
+        _2 = Foo { a: const 1_i32, b: const 2_i32 }; // scope 0 at $DIR/aggregate_exprs.rs:+7:13: +10:14
+        _3 = Bar::Foo(move _2, _1);      // scope 0 at $DIR/aggregate_exprs.rs:+11:13: +11:39
+        _0 = Onion { neon: ((_3 as variant#0).1: i32) }; // scope 0 at $DIR/aggregate_exprs.rs:+12:13: +12:58
+        return;                          // scope 0 at $DIR/aggregate_exprs.rs:+13:13: +13:21
+    }
+}
diff --git a/tests/mir-opt/building/custom/aggregate_exprs.array.built.after.mir b/tests/mir-opt/building/custom/aggregate_exprs.array.built.after.mir
new file mode 100644
index 00000000000..30d12897331
--- /dev/null
+++ b/tests/mir-opt/building/custom/aggregate_exprs.array.built.after.mir
@@ -0,0 +1,15 @@
+// MIR for `array` after built
+
+fn array() -> [i32; 2] {
+    let mut _0: [i32; 2];                // return place in scope 0 at $DIR/aggregate_exprs.rs:+0:15: +0:23
+    let mut _1: [i32; 2];                // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+    let mut _2: i32;                     // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+    bb0: {
+        _1 = [const 42_i32, const 43_i32]; // scope 0 at $DIR/aggregate_exprs.rs:+5:13: +5:25
+        _2 = const 1_i32;                // scope 0 at $DIR/aggregate_exprs.rs:+6:13: +6:20
+        _1 = [_2, const 2_i32];          // scope 0 at $DIR/aggregate_exprs.rs:+7:13: +7:25
+        _0 = move _1;                    // scope 0 at $DIR/aggregate_exprs.rs:+8:13: +8:26
+        return;                          // scope 0 at $DIR/aggregate_exprs.rs:+9:13: +9:21
+    }
+}
diff --git a/tests/mir-opt/building/custom/aggregate_exprs.rs b/tests/mir-opt/building/custom/aggregate_exprs.rs
new file mode 100644
index 00000000000..554c9c03ba4
--- /dev/null
+++ b/tests/mir-opt/building/custom/aggregate_exprs.rs
@@ -0,0 +1,71 @@
+#![feature(custom_mir, core_intrinsics)]
+
+extern crate core;
+use core::intrinsics::mir::*;
+
+// EMIT_MIR aggregate_exprs.tuple.built.after.mir
+#[custom_mir(dialect = "built")]
+fn tuple() -> (i32, bool) {
+    mir!(
+        {
+            RET = (1, true);
+            Return()
+        }
+    )
+}
+
+// EMIT_MIR aggregate_exprs.array.built.after.mir
+#[custom_mir(dialect = "built")]
+fn array() -> [i32; 2] {
+    mir!(
+        let x: [i32; 2];
+        let one: i32;
+        {
+            x = [42, 43];
+            one = 1;
+            x = [one, 2];
+            RET = Move(x);
+            Return()
+        }
+    )
+}
+
+struct Foo {
+    a: i32,
+    b: i32,
+}
+
+enum Bar {
+    Foo(Foo, i32),
+}
+
+union Onion {
+    neon: i32,
+    noun: f32,
+}
+
+// EMIT_MIR aggregate_exprs.adt.built.after.mir
+#[custom_mir(dialect = "built")]
+fn adt() -> Onion {
+    mir!(
+        let one: i32;
+        let x: Foo;
+        let y: Bar;
+        {
+            one = 1;
+            x = Foo {
+                a: 1,
+                b: 2,
+            };
+            y = Bar::Foo(Move(x), one);
+            RET = Onion { neon: Field(Variant(y, 0), 1) };
+            Return()
+        }
+    )
+}
+
+fn main() {
+    assert_eq!(tuple(), (1, true));
+    assert_eq!(array(), [1, 2]);
+    assert_eq!(unsafe { adt().neon }, 1);
+}
diff --git a/tests/mir-opt/building/custom/aggregate_exprs.tuple.built.after.mir b/tests/mir-opt/building/custom/aggregate_exprs.tuple.built.after.mir
new file mode 100644
index 00000000000..5fe45ccc90c
--- /dev/null
+++ b/tests/mir-opt/building/custom/aggregate_exprs.tuple.built.after.mir
@@ -0,0 +1,10 @@
+// MIR for `tuple` after built
+
+fn tuple() -> (i32, bool) {
+    let mut _0: (i32, bool);             // return place in scope 0 at $DIR/aggregate_exprs.rs:+0:15: +0:26
+
+    bb0: {
+        _0 = (const 1_i32, const true);  // scope 0 at $DIR/aggregate_exprs.rs:+3:13: +3:28
+        return;                          // scope 0 at $DIR/aggregate_exprs.rs:+4:13: +4:21
+    }
+}