about summary refs log tree commit diff
path: root/compiler/rustc_const_eval
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2023-01-23 22:15:55 +0000
committerCamille GILLOT <gillot.camille@gmail.com>2023-02-02 23:09:51 +0000
commitfeccf469fbeb96c97d3b6a5f3186867afe0571f5 (patch)
treee9e68d0c00dcdb2a296f8116b251e589cbfbec2d /compiler/rustc_const_eval
parent0241c29123c7a49b5fdcc99e32b605124abe4e09 (diff)
downloadrust-feccf469fbeb96c97d3b6a5f3186867afe0571f5.tar.gz
rust-feccf469fbeb96c97d3b6a5f3186867afe0571f5.zip
Interpret aggregates.
Diffstat (limited to 'compiler/rustc_const_eval')
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs9
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs20
2 files changed, 16 insertions, 13 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index 274af61ee7c..5c00dc21d04 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -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
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index d101937fd74..7e00d90342e 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -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, _) => {