diff --git a/src/abi.rs b/src/abi.rs index 0aa8e299bb0..75b35b6fac5 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -399,8 +399,8 @@ fn local_place<'tcx>( fields: _, largest_niche: _, } = details; - match place { - CPlace::Stack(stack_slot, _) => fx.add_entity_comment( + match *place.inner() { + CPlaceInner::Stack(stack_slot) => fx.add_entity_comment( stack_slot, format!( "{:?}: {:?} size={} align={},{}", @@ -411,7 +411,7 @@ fn local_place<'tcx>( align.pref.bytes(), ), ), - CPlace::NoPlace(_) => fx.add_global_comment(format!( + CPlaceInner::NoPlace => fx.add_global_comment(format!( "zst {:?}: {:?} size={} align={}, {}", local, ty, diff --git a/src/intrinsics.rs b/src/intrinsics.rs index 2cec9c57143..354513ac57b 100644 --- a/src/intrinsics.rs +++ b/src/intrinsics.rs @@ -565,14 +565,15 @@ pub fn codegen_intrinsic_call<'tcx>( ret.write_cvalue(fx, CValue::by_ref(addr, dst_layout)) }; init, () { - if ret.layout().abi == Abi::Uninhabited { + let layout = ret.layout(); + if layout.abi == Abi::Uninhabited { crate::trap::trap_panic(fx, "[panic] Called intrinsic::init for uninhabited type."); return; } - match ret { - CPlace::NoPlace(_layout) => {} - CPlace::Var(var, layout) => { + match *ret.inner() { + CPlaceInner::NoPlace => {} + CPlaceInner::Var(var) => { let clif_ty = fx.clif_type(layout.ty).unwrap(); let val = match clif_ty { types::I8 | types::I16 | types::I32 | types::I64 => fx.bcx.ins().iconst(clif_ty, 0), @@ -596,13 +597,14 @@ pub fn codegen_intrinsic_call<'tcx>( } }; uninit, () { - if ret.layout().abi == Abi::Uninhabited { + let layout = ret.layout(); + if layout.abi == Abi::Uninhabited { crate::trap::trap_panic(fx, "[panic] Called intrinsic::uninit for uninhabited type."); return; } - match ret { - CPlace::NoPlace(_layout) => {}, - CPlace::Var(var, layout) => { + match *ret.inner() { + CPlaceInner::NoPlace => {}, + CPlaceInner::Var(var) => { let clif_ty = fx.clif_type(layout.ty).unwrap(); let val = match clif_ty { types::I8 | types::I16 | types::I32 | types::I64 => fx.bcx.ins().iconst(clif_ty, 42), @@ -618,7 +620,7 @@ pub fn codegen_intrinsic_call<'tcx>( }; fx.bcx.def_var(mir_var(var), val); } - CPlace::Addr(_, _, _) | CPlace::Stack(_, _) => { + CPlaceInner::Addr(_, _) | CPlaceInner::Stack(_) => { // Don't write to `ret`, as the destination memory is already uninitialized. } } diff --git a/src/lib.rs b/src/lib.rs index 21c7f3af226..d84a6e8199a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -102,7 +102,7 @@ mod prelude { pub use crate::debuginfo::{DebugContext, FunctionDebugContext}; pub use crate::trap::*; pub use crate::unimpl::{unimpl, with_unimpl_span}; - pub use crate::value_and_place::{CValue, CPlace}; + pub use crate::value_and_place::{CValue, CPlace, CPlaceInner}; pub use crate::{Caches, CodegenCx}; pub struct PrintOnPanic String>(pub F); diff --git a/src/value_and_place.rs b/src/value_and_place.rs index f018ed0a2ba..b300db2ecfc 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -163,25 +163,33 @@ impl<'tcx> CValue<'tcx> { /// A place where you can write a value to or read a value from #[derive(Debug, Copy, Clone)] -pub enum CPlace<'tcx> { - Var(Local, TyLayout<'tcx>), - Addr(Value, Option, TyLayout<'tcx>), - Stack(StackSlot, TyLayout<'tcx>), - NoPlace(TyLayout<'tcx>), +pub struct CPlace<'tcx> { + inner: CPlaceInner, + layout: TyLayout<'tcx>, +} + +#[derive(Debug, Copy, Clone)] +pub enum CPlaceInner { + Var(Local), + Addr(Value, Option), + Stack(StackSlot), + NoPlace, } impl<'tcx> CPlace<'tcx> { pub fn layout(&self) -> TyLayout<'tcx> { - match *self { - CPlace::Var(_, layout) - | CPlace::Addr(_, _, layout) - | CPlace::Stack(_, layout) - | CPlace::NoPlace(layout) => layout, - } + self.layout + } + + pub fn inner(&self) -> &CPlaceInner { + &self.inner } pub fn no_place(layout: TyLayout<'tcx>) -> CPlace<'tcx> { - CPlace::NoPlace(layout) + CPlace{ + inner: CPlaceInner::NoPlace, + layout + } } pub fn new_stack_slot( @@ -191,7 +199,10 @@ impl<'tcx> CPlace<'tcx> { let layout = fx.layout_of(ty); assert!(!layout.is_unsized()); if layout.size.bytes() == 0 { - return CPlace::NoPlace(layout); + return CPlace { + inner: CPlaceInner::NoPlace, + layout, + }; } let stack_slot = fx.bcx.create_stack_slot(StackSlotData { @@ -199,7 +210,10 @@ impl<'tcx> CPlace<'tcx> { size: layout.size.bytes() as u32, offset: None, }); - CPlace::Stack(stack_slot, layout) + CPlace { + inner: CPlaceInner::Stack(stack_slot), + layout, + } } pub fn new_var( @@ -209,29 +223,39 @@ impl<'tcx> CPlace<'tcx> { ) -> CPlace<'tcx> { fx.bcx .declare_var(mir_var(local), fx.clif_type(layout.ty).unwrap()); - CPlace::Var(local, layout) + CPlace { + inner: CPlaceInner::Var(local), + layout, + } } pub fn for_addr(addr: Value, layout: TyLayout<'tcx>) -> CPlace<'tcx> { - CPlace::Addr(addr, None, layout) + CPlace { + inner: CPlaceInner::Addr(addr, None), + layout, + } } pub fn for_addr_with_extra(addr: Value, extra: Value, layout: TyLayout<'tcx>) -> CPlace<'tcx> { - CPlace::Addr(addr, Some(extra), layout) + CPlace { + inner: CPlaceInner::Addr(addr, Some(extra)), + layout, + } } pub fn to_cvalue(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>) -> CValue<'tcx> { - match self { - CPlace::Var(var, layout) => CValue::by_val(fx.bcx.use_var(mir_var(var)), layout), - CPlace::Addr(addr, extra, layout) => { + let layout = self.layout(); + match self.inner { + CPlaceInner::Var(var) => CValue::by_val(fx.bcx.use_var(mir_var(var)), layout), + CPlaceInner::Addr(addr, extra) => { assert!(extra.is_none(), "unsized values are not yet supported"); CValue::by_ref(addr, layout) } - CPlace::Stack(stack_slot, layout) => CValue::by_ref( + CPlaceInner::Stack(stack_slot) => CValue::by_ref( fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0), layout, ), - CPlace::NoPlace(layout) => CValue::by_ref( + CPlaceInner::NoPlace => CValue::by_ref( fx.bcx .ins() .iconst(fx.pointer_type, fx.pointer_type.bytes() as i64), @@ -251,14 +275,14 @@ impl<'tcx> CPlace<'tcx> { self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>, ) -> (Value, Option) { - match self { - CPlace::Addr(addr, extra, _layout) => (addr, extra), - CPlace::Stack(stack_slot, _layout) => ( + match self.inner { + CPlaceInner::Addr(addr, extra) => (addr, extra), + CPlaceInner::Stack(stack_slot) => ( fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0), None, ), - CPlace::NoPlace(_) => (fx.bcx.ins().iconst(fx.pointer_type, 45), None), - CPlace::Var(_, _) => bug!("Expected CPlace::Addr, found CPlace::Var"), + CPlaceInner::NoPlace => (fx.bcx.ins().iconst(fx.pointer_type, 45), None), + CPlaceInner::Var(_) => bug!("Expected CPlace::Addr, found CPlace::Var"), } } @@ -327,24 +351,24 @@ impl<'tcx> CPlace<'tcx> { assert_assignable(fx, from_ty, to_ty); - let (addr, dst_layout) = match self { - CPlace::Var(var, _) => { + let dst_layout = self.layout(); + let addr = match self.inner { + CPlaceInner::Var(var) => { let data = from.load_scalar(fx); fx.bcx.def_var(mir_var(var), data); return; } - CPlace::Addr(addr, None, dst_layout) => (addr, dst_layout), - CPlace::Stack(stack_slot, dst_layout) => ( - fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0), - dst_layout, - ), - CPlace::NoPlace(layout) => { - if layout.abi != Abi::Uninhabited { - assert_eq!(layout.size.bytes(), 0, "{:?}", layout); + CPlaceInner::Addr(addr, None) => addr, + CPlaceInner::Stack(stack_slot) => { + fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0) + } + CPlaceInner::NoPlace => { + if dst_layout.abi != Abi::Uninhabited { + assert_eq!(dst_layout.size.bytes(), 0, "{:?}", dst_layout); } return; } - CPlace::Addr(_, _, _) => bug!("Can't write value to unsized place {:?}", self), + CPlaceInner::Addr(_, Some(_)) => bug!("Can't write value to unsized place {:?}", self), }; match from.0 { @@ -395,13 +419,11 @@ impl<'tcx> CPlace<'tcx> { let (base, extra) = self.to_addr_maybe_unsized(fx); let (field_ptr, field_layout) = codegen_field(fx, base, layout, field); - let extra = if field_layout.is_unsized() { - assert!(extra.is_some()); - extra + if field_layout.is_unsized() { + CPlace::for_addr_with_extra(field_ptr, extra.unwrap(), field_layout) } else { - None - }; - CPlace::Addr(field_ptr, extra, field_layout) + CPlace::for_addr(field_ptr, field_layout) + } } pub fn place_index( @@ -420,16 +442,16 @@ impl<'tcx> CPlace<'tcx> { .ins() .imul_imm(index, elem_layout.size.bytes() as i64); - CPlace::Addr(fx.bcx.ins().iadd(addr, offset), None, elem_layout) + CPlace::for_addr(fx.bcx.ins().iadd(addr, offset), elem_layout) } pub fn place_deref(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>) -> CPlace<'tcx> { let inner_layout = fx.layout_of(self.layout().ty.builtin_deref(true).unwrap().ty); if !inner_layout.is_unsized() { - CPlace::Addr(self.to_cvalue(fx).load_scalar(fx), None, inner_layout) + CPlace::for_addr(self.to_cvalue(fx).load_scalar(fx), inner_layout) } else { let (addr, extra) = self.to_cvalue(fx).load_scalar_pair(fx); - CPlace::Addr(addr, Some(extra), inner_layout) + CPlace::for_addr_with_extra(addr, extra, inner_layout) } } @@ -446,14 +468,15 @@ impl<'tcx> CPlace<'tcx> { pub fn unchecked_cast_to(self, layout: TyLayout<'tcx>) -> Self { assert!(!self.layout().is_unsized()); - match self { - CPlace::Var(var, _) => CPlace::Var(var, layout), - CPlace::Addr(addr, extra, _) => CPlace::Addr(addr, extra, layout), - CPlace::Stack(stack_slot, _) => CPlace::Stack(stack_slot, layout), - CPlace::NoPlace(_) => { + match self.inner { + CPlaceInner::NoPlace => { assert!(layout.size.bytes() == 0); - CPlace::NoPlace(layout) } + _ => {} + } + CPlace { + inner: self.inner, + layout, } }