Interpret aggregates.

This commit is contained in:
Camille GILLOT 2023-01-23 22:15:55 +00:00
parent 0241c29123
commit feccf469fb
4 changed files with 29 additions and 21 deletions

View File

@ -13,6 +13,7 @@ use rustc_middle::ty::cast::{CastTy, IntTy};
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
use rustc_middle::ty::{self, adjustment::PointerCast, Instance, Ty, TyCtxt};
use rustc_span::source_map::{Span, DUMMY_SP};
use rustc_target::abi::VariantIdx;
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
#[instrument(level = "trace", skip(self, bx))]
@ -115,6 +116,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
(dest, active_field_index)
}
}
mir::AggregateKind::Generator(..) => {
dest.codegen_set_discr(bx, VariantIdx::from_u32(0));
(dest, None)
}
_ => (dest, None),
};
for (i, operand) in operands.iter().enumerate() {

View File

@ -774,15 +774,6 @@ where
variant_index: VariantIdx,
dest: &PlaceTy<'tcx, M::Provenance>,
) -> InterpResult<'tcx> {
// This must be an enum or generator.
match dest.layout.ty.kind() {
ty::Adt(adt, _) => assert!(adt.is_enum()),
ty::Generator(..) => {}
_ => span_bug!(
self.cur_span(),
"write_discriminant called on non-variant-type (neither enum nor generator)"
),
}
// Layout computation excludes uninhabited variants from consideration
// therefore there's no way to represent those variants in the given layout.
// Essentially, uninhabited variants do not have a tag that corresponds to their

View File

@ -7,6 +7,7 @@ use either::Either;
use rustc_middle::mir;
use rustc_middle::mir::interpret::{InterpResult, Scalar};
use rustc_middle::ty::layout::LayoutOf;
use rustc_target::abi::VariantIdx;
use super::{ImmTy, InterpCx, Machine};
@ -199,13 +200,24 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
Aggregate(box ref kind, ref operands) => {
assert!(matches!(kind, mir::AggregateKind::Array(..)));
self.write_uninit(&dest)?;
let (variant_index, variant_dest, active_field_index) = match *kind {
mir::AggregateKind::Adt(_, variant_index, _, _, active_field_index) => {
let variant_dest = self.place_downcast(&dest, variant_index)?;
(variant_index, variant_dest, active_field_index)
}
_ => (VariantIdx::from_u32(0), dest.clone(), None),
};
if active_field_index.is_some() {
assert_eq!(operands.len(), 1);
}
for (field_index, operand) in operands.iter().enumerate() {
let op = self.eval_operand(operand, None)?;
let field_dest = self.place_field(&dest, field_index)?;
let field_index = active_field_index.unwrap_or(field_index);
let field_dest = self.place_field(&variant_dest, field_index)?;
let op = self.eval_operand(operand, Some(field_dest.layout))?;
self.copy_op(&op, &field_dest, /*allow_transmute*/ false)?;
}
self.write_discriminant(variant_index, &dest)?;
}
Repeat(ref operand, _) => {

View File

@ -27,19 +27,19 @@ alloc1 (static: FOO, size: 16, align: 8) {
alloc18 (size: 72, align: 8) {
0x00 00 00 00 00 __ __ __ __ alloc5 ....
0x10 00 00 00 00 00 00 00 00 00 00 00 00 __ __ __ __ ............
0x20 alloc9 02 00 00 00 00 00 00 00 ........
0x30 01 00 00 00 2a 00 00 00 alloc14 ....*...
0x20 alloc8 02 00 00 00 00 00 00 00 ........
0x30 01 00 00 00 2a 00 00 00 alloc13 ....*...
0x40 03 00 00 00 00 00 00 00 ........
}
alloc5 (size: 0, align: 8) {}
alloc9 (size: 32, align: 8) {
0x00 alloc8 03 00 00 00 00 00 00 00 ........
alloc8 (size: 32, align: 8) {
0x00 alloc9 03 00 00 00 00 00 00 00 ........
0x10 alloc10 03 00 00 00 00 00 00 00 ........
}
alloc8 (size: 3, align: 1) {
alloc9 (size: 3, align: 1) {
66 6f 6f foo
}
@ -47,13 +47,13 @@ alloc10 (size: 3, align: 1) {
62 61 72 bar
}
alloc14 (size: 48, align: 8) {
0x00 alloc13 03 00 00 00 00 00 00 00 ........
alloc13 (size: 48, align: 8) {
0x00 alloc14 03 00 00 00 00 00 00 00 ........
0x10 alloc15 03 00 00 00 00 00 00 00 ........
0x20 alloc16 04 00 00 00 00 00 00 00 ........
}
alloc13 (size: 3, align: 1) {
alloc14 (size: 3, align: 1) {
6d 65 68 meh
}