Skip to content

Commit

Permalink
Rollup merge of rust-lang#109390 - cbeuw:aggregate-lit, r=oli-obk
Browse files Browse the repository at this point in the history
Custom MIR: Support aggregate expressions

Add support for tuple, array and ADT expressions in custom mir

r? ```@oli-obk``` or ```@tmiasko``` or ```@JakobDegen```
  • Loading branch information
Noratrieb authored Mar 21, 2023
2 parents bb98a8e + f404f33 commit a352a17
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 1 deletion.
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/mir/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
22 changes: 22 additions & 0 deletions compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
)
}
Expand Down
16 changes: 16 additions & 0 deletions tests/mir-opt/building/custom/aggregate_exprs.adt.built.after.mir
Original file line number Diff line number Diff line change
@@ -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
}
}
Original file line number Diff line number Diff line change
@@ -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
}
}
71 changes: 71 additions & 0 deletions tests/mir-opt/building/custom/aggregate_exprs.rs
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -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
}
}

0 comments on commit a352a17

Please sign in to comment.