about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2018-04-04 11:07:17 +0200
committerGitHub <noreply@github.com>2018-04-04 11:07:17 +0200
commitb5ceda86aa4a374810a214cfd5366c24f6048342 (patch)
treef918074b61c7e67ef061cba93b5373f3012e7dea
parent6c8b8091fc73f5cec88d838d32fa165f54ac4ead (diff)
parent7a28ffce90271b82f89fd6a3fa110b5c25795ce2 (diff)
downloadrust-b5ceda86aa4a374810a214cfd5366c24f6048342.tar.gz
rust-b5ceda86aa4a374810a214cfd5366c24f6048342.zip
Rollup merge of #49540 - bjorn3:fix_miri_discriminant, r=oli-obk
Fix miri Discriminant() for non-ADT

Fixes #49327
-rw-r--r--src/librustc_mir/interpret/eval_context.rs29
1 files changed, 19 insertions, 10 deletions
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index b8bfcd756cd..cf3241fe9be 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -743,20 +743,29 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
 
             Discriminant(ref place) => {
                 let ty = self.place_ty(place);
+                let layout = self.layout_of(ty)?;
                 let place = self.eval_place(place)?;
                 let discr_val = self.read_discriminant_value(place, ty)?;
-                if let ty::TyAdt(adt_def, _) = ty.sty {
-                    trace!("Read discriminant {}, valid discriminants {:?}", discr_val, adt_def.discriminants(*self.tcx).collect::<Vec<_>>());
-                    if adt_def.discriminants(*self.tcx).all(|v| {
-                        discr_val != v.val
-                    })
-                    {
-                        return err!(InvalidDiscriminant);
+                match layout.variants {
+                    layout::Variants::Single { index } => {
+                        assert_eq!(discr_val, index as u128);
+                    }
+                    layout::Variants::Tagged { .. } |
+                    layout::Variants::NicheFilling { .. } => {
+                        if let ty::TyAdt(adt_def, _) = ty.sty {
+                            trace!("Read discriminant {}, valid discriminants {:?}", discr_val, adt_def.discriminants(*self.tcx).collect::<Vec<_>>());
+                            if adt_def.discriminants(*self.tcx).all(|v| {
+                                discr_val != v.val
+                            })
+                            {
+                                return err!(InvalidDiscriminant);
+                            }
+                        } else {
+                            bug!("rustc only generates Rvalue::Discriminant for enums");
+                        }
                     }
-                    self.write_primval(dest, PrimVal::Bytes(discr_val), dest_ty)?;
-                } else {
-                    bug!("rustc only generates Rvalue::Discriminant for enums");
                 }
+                self.write_primval(dest, PrimVal::Bytes(discr_val), dest_ty)?;
             }
         }