diff options
| author | Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> | 2022-06-29 14:18:55 +0000 |
|---|---|---|
| committer | Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> | 2022-06-30 07:47:07 +0000 |
| commit | 7839cb963f747edff90b72efc6094e7184f6ef0e (patch) | |
| tree | 5bf0f8fa756c9bfd3867445cd5a97c91066a5d04 /compiler/rustc_const_eval/src | |
| parent | 0e674b3ec5e2c238e6756d512fa39efc1ceeb74a (diff) | |
| download | rust-7839cb963f747edff90b72efc6094e7184f6ef0e.tar.gz rust-7839cb963f747edff90b72efc6094e7184f6ef0e.zip | |
Change enum->int casts to not go through MIR casts.
Instead we generate a discriminant rvalue and cast the result of that.
Diffstat (limited to 'compiler/rustc_const_eval/src')
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/cast.rs | 25 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/transform/validate.rs | 32 |
2 files changed, 30 insertions, 27 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index fb484fba9fd..4835b7969b2 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -8,7 +8,7 @@ use rustc_middle::mir::CastKind; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::layout::{IntegerExt, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, FloatTy, Ty, TypeAndMut}; -use rustc_target::abi::{Integer, Variants}; +use rustc_target::abi::Integer; use rustc_type_ir::sty::TyKind::*; use super::{ @@ -127,12 +127,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Float(FloatTy::F64) => { return Ok(self.cast_from_float(src.to_scalar()?.to_f64()?, cast_ty).into()); } - // The rest is integer/pointer-"like", including fn ptr casts and casts from enums that - // are represented as integers. + // The rest is integer/pointer-"like", including fn ptr casts _ => assert!( src.layout.ty.is_bool() || src.layout.ty.is_char() - || src.layout.ty.is_enum() || src.layout.ty.is_integral() || src.layout.ty.is_any_ptr(), "Unexpected cast from type {:?}", @@ -142,25 +140,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // # First handle non-scalar source values. - // Handle cast from a ZST enum (0 or 1 variants). - match src.layout.variants { - Variants::Single { index } => { - if src.layout.abi.is_uninhabited() { - // This is dead code, because an uninhabited enum is UB to - // instantiate. - throw_ub!(Unreachable); - } - if let Some(discr) = src.layout.ty.discriminant_for_variant(*self.tcx, index) { - assert!(src.layout.is_zst()); - let discr_layout = self.layout_of(discr.ty)?; - - let scalar = Scalar::from_uint(discr.val, discr_layout.layout.size()); - return Ok(self.cast_from_int_like(scalar, discr_layout, cast_ty)?.into()); - } - } - Variants::Multiple { .. } => {} - } - // Handle casting any ptr to raw ptr (might be a fat ptr). if src.layout.ty.is_any_ptr() && cast_ty.is_unsafe_ptr() { let dest_layout = self.layout_of(cast_ty)?; diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 66d66ea9510..dce4a68e811 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -7,9 +7,9 @@ use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::visit::NonUseContext::VarDebugInfo; use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::{ - traversal, AggregateKind, BasicBlock, BinOp, Body, BorrowKind, Local, Location, MirPass, - MirPhase, Operand, Place, PlaceElem, PlaceRef, ProjectionElem, Rvalue, SourceScope, Statement, - StatementKind, Terminator, TerminatorKind, UnOp, START_BLOCK, + traversal, AggregateKind, BasicBlock, BinOp, Body, BorrowKind, CastKind, Local, Location, + MirPass, MirPhase, Operand, Place, PlaceElem, PlaceRef, ProjectionElem, Rvalue, SourceScope, + Statement, StatementKind, Terminator, TerminatorKind, UnOp, START_BLOCK, }; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeFoldable}; @@ -361,6 +361,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ); } } + Rvalue::Ref(..) => {} Rvalue::Len(p) => { let pty = p.ty(&self.body.local_decls, self.tcx).ty; check_kinds!( @@ -503,7 +504,30 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { let a = operand.ty(&self.body.local_decls, self.tcx); check_kinds!(a, "Cannot shallow init type {:?}", ty::RawPtr(..)); } - _ => {} + Rvalue::Cast(kind, operand, target_type) => { + match kind { + CastKind::Misc => { + let op_ty = operand.ty(self.body, self.tcx); + if op_ty.is_enum() { + self.fail( + location, + format!( + "enum -> int casts should go through `Rvalue::Discriminant`: {operand:?}:{op_ty} as {target_type}", + ), + ); + } + } + // Nothing to check here + CastKind::PointerFromExposedAddress + | CastKind::PointerExposeAddress + | CastKind::Pointer(_) => {} + } + } + Rvalue::Repeat(_, _) + | Rvalue::ThreadLocalRef(_) + | Rvalue::AddressOf(_, _) + | Rvalue::NullaryOp(_, _) + | Rvalue::Discriminant(_) => {} } self.super_rvalue(rvalue, location); } |
