Skip to content

Commit 8e4e55e

Browse files
committed
Support aggregate expressions
1 parent ab9bb3e commit 8e4e55e

File tree

5 files changed

+137
-0
lines changed

5 files changed

+137
-0
lines changed

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,31 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
166166
let cast_kind = mir_cast_kind(source_ty, expr.ty);
167167
Ok(Rvalue::Cast(cast_kind, source, expr.ty))
168168
},
169+
ExprKind::Tuple { fields } => Ok(
170+
Rvalue::Aggregate(
171+
Box::new(AggregateKind::Tuple),
172+
fields.iter().map(|e| self.parse_operand(*e)).collect::<Result<_, _>>()?
173+
)
174+
),
175+
ExprKind::Array { fields } => {
176+
let elem_ty = match expr.ty.kind() {
177+
ty::Array(ty, ..) => ty,
178+
_ => unreachable!("ty is array"),
179+
};
180+
Ok(Rvalue::Aggregate(
181+
Box::new(AggregateKind::Array(*elem_ty)),
182+
fields.iter().map(|e| self.parse_operand(*e)).collect::<Result<_, _>>()?
183+
))
184+
},
185+
ExprKind::Adt(box AdtExpr{ adt_def, variant_index, substs, fields, .. }) => {
186+
let is_union = adt_def.is_union();
187+
let active_field_index = is_union.then(|| fields[0].name.index());
188+
189+
Ok(Rvalue::Aggregate(
190+
Box::new(AggregateKind::Adt(adt_def.did(), *variant_index, substs, None, active_field_index)),
191+
fields.iter().map(|f| self.parse_operand(f.expr)).collect::<Result<_, _>>()?
192+
))
193+
},
169194
_ => self.parse_operand(expr_id).map(Rvalue::Use),
170195
)
171196
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// MIR for `adt` after built
2+
3+
fn adt() -> Onion {
4+
let mut _0: Onion; // return place in scope 0 at $DIR/aggregate_exprs.rs:+0:13: +0:18
5+
let mut _1: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
6+
let mut _2: Foo; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
7+
let mut _3: Bar; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
8+
9+
bb0: {
10+
_1 = const 1_i32; // scope 0 at $DIR/aggregate_exprs.rs:+6:13: +6:20
11+
_2 = Foo { a: const 1_i32, b: const 2_i32 }; // scope 0 at $DIR/aggregate_exprs.rs:+7:13: +10:14
12+
_3 = Bar::Foo(move _2, _1); // scope 0 at $DIR/aggregate_exprs.rs:+11:13: +11:39
13+
_0 = Onion { neon: ((_3 as variant#0).1: i32) }; // scope 0 at $DIR/aggregate_exprs.rs:+12:13: +12:58
14+
return; // scope 0 at $DIR/aggregate_exprs.rs:+13:13: +13:21
15+
}
16+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// MIR for `array` after built
2+
3+
fn array() -> [i32; 2] {
4+
let mut _0: [i32; 2]; // return place in scope 0 at $DIR/aggregate_exprs.rs:+0:15: +0:23
5+
let mut _1: [i32; 2]; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
6+
let mut _2: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
7+
8+
bb0: {
9+
_1 = [const 42_i32, const 43_i32]; // scope 0 at $DIR/aggregate_exprs.rs:+5:13: +5:25
10+
_2 = const 1_i32; // scope 0 at $DIR/aggregate_exprs.rs:+6:13: +6:20
11+
_1 = [_2, const 2_i32]; // scope 0 at $DIR/aggregate_exprs.rs:+7:13: +7:25
12+
_0 = move _1; // scope 0 at $DIR/aggregate_exprs.rs:+8:13: +8:26
13+
return; // scope 0 at $DIR/aggregate_exprs.rs:+9:13: +9:21
14+
}
15+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#![feature(custom_mir, core_intrinsics)]
2+
3+
extern crate core;
4+
use core::intrinsics::mir::*;
5+
6+
// EMIT_MIR aggregate_exprs.tuple.built.after.mir
7+
#[custom_mir(dialect = "built")]
8+
fn tuple() -> (i32, bool) {
9+
mir!(
10+
{
11+
RET = (1, true);
12+
Return()
13+
}
14+
)
15+
}
16+
17+
// EMIT_MIR aggregate_exprs.array.built.after.mir
18+
#[custom_mir(dialect = "built")]
19+
fn array() -> [i32; 2] {
20+
mir!(
21+
let x: [i32; 2];
22+
let one: i32;
23+
{
24+
x = [42, 43];
25+
one = 1;
26+
x = [one, 2];
27+
RET = Move(x);
28+
Return()
29+
}
30+
)
31+
}
32+
33+
struct Foo {
34+
a: i32,
35+
b: i32,
36+
}
37+
38+
enum Bar {
39+
Foo(Foo, i32),
40+
}
41+
42+
union Onion {
43+
neon: i32,
44+
noun: f32,
45+
}
46+
47+
// EMIT_MIR aggregate_exprs.adt.built.after.mir
48+
#[custom_mir(dialect = "built")]
49+
fn adt() -> Onion {
50+
mir!(
51+
let one: i32;
52+
let x: Foo;
53+
let y: Bar;
54+
{
55+
one = 1;
56+
x = Foo {
57+
a: 1,
58+
b: 2,
59+
};
60+
y = Bar::Foo(Move(x), one);
61+
RET = Onion { neon: Field(Variant(y, 0), 1) };
62+
Return()
63+
}
64+
)
65+
}
66+
67+
fn main() {
68+
assert_eq!(tuple(), (1, true));
69+
assert_eq!(array(), [1, 2]);
70+
assert_eq!(unsafe { adt().neon }, 1);
71+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// MIR for `tuple` after built
2+
3+
fn tuple() -> (i32, bool) {
4+
let mut _0: (i32, bool); // return place in scope 0 at $DIR/aggregate_exprs.rs:+0:15: +0:26
5+
6+
bb0: {
7+
_0 = (const 1_i32, const true); // scope 0 at $DIR/aggregate_exprs.rs:+3:13: +3:28
8+
return; // scope 0 at $DIR/aggregate_exprs.rs:+4:13: +4:21
9+
}
10+
}

0 commit comments

Comments
 (0)