From bab8113954bd24e63a1e51f00088d761560ddd98 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 16 Feb 2019 17:18:38 +0100 Subject: [PATCH] Fix discriminant_value intrinsic Fixes #349 --- example/std_example.rs | 8 ++++++++ src/base.rs | 12 +++++++----- src/intrinsics.rs | 4 +++- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/example/std_example.rs b/example/std_example.rs index cd0a88c85fc..ce74efee8a8 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -15,4 +15,12 @@ fn main() { static ONCE: std::sync::Once = std::sync::ONCE_INIT; ONCE.call_once(|| {}); + + LoopState::Continue(()) == LoopState::Break(()); +} + +#[derive(PartialEq)] +enum LoopState { + Continue(()), + Break(()) } diff --git a/src/base.rs b/src/base.rs index 556e01aa3a2..5eb1819e3cc 100644 --- a/src/base.rs +++ b/src/base.rs @@ -570,7 +570,9 @@ fn trans_stmt<'a, 'tcx: 'a>( lval.write_cvalue(fx, CValue::ByVal(res, dest_layout)); } (ty::Adt(adt_def, _substs), ty::Uint(_)) | (ty::Adt(adt_def, _substs), ty::Int(_)) if adt_def.is_enum() => { - let discr = trans_get_discriminant(fx, operand, fx.layout_of(to_ty)); + // FIXME avoid forcing to stack + let place = CPlace::Addr(operand.force_stack(fx), None, operand.layout()); + let discr = trans_get_discriminant(fx, place, fx.layout_of(to_ty)); lval.write_cvalue(fx, discr); } _ => unimpl!("rval misc {:?} {:?}", from_ty, to_ty), @@ -584,7 +586,7 @@ fn trans_stmt<'a, 'tcx: 'a>( operand.unsize_value(fx, lval); } Rvalue::Discriminant(place) => { - let place = trans_place(fx, place).to_cvalue(fx); + let place = trans_place(fx, place); let discr = trans_get_discriminant(fx, place, dest_layout); lval.write_cvalue(fx, discr); } @@ -680,10 +682,10 @@ fn codegen_array_len<'a, 'tcx: 'a>( pub fn trans_get_discriminant<'a, 'tcx: 'a>( fx: &mut FunctionCx<'a, 'tcx, impl Backend>, - value: CValue<'tcx>, + place: CPlace<'tcx>, dest_layout: TyLayout<'tcx>, ) -> CValue<'tcx> { - let layout = value.layout(); + let layout = place.layout(); if layout.abi == layout::Abi::Uninhabited { trap_unreachable(&mut fx.bcx); @@ -701,7 +703,7 @@ pub fn trans_get_discriminant<'a, 'tcx: 'a>( layout::Variants::Tagged { .. } | layout::Variants::NicheFilling { .. } => {} } - let discr = value.value_field(fx, mir::Field::new(0)); + let discr = place.place_field(fx, mir::Field::new(0)).to_cvalue(fx); let discr_ty = discr.layout().ty; let lldiscr = discr.load_scalar(fx); match layout.variants { diff --git a/src/intrinsics.rs b/src/intrinsics.rs index 18c261c9903..2068bd9e508 100644 --- a/src/intrinsics.rs +++ b/src/intrinsics.rs @@ -141,7 +141,9 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>( } }; discriminant_value, (c val) { - let discr = crate::base::trans_get_discriminant(fx, val, ret.layout()); + let pointee_layout = fx.layout_of(val.layout().ty.builtin_deref(true).unwrap().ty); + let place = CPlace::Addr(val.load_scalar(fx), None, pointee_layout); + let discr = crate::base::trans_get_discriminant(fx, place, ret.layout()); ret.write_cvalue(fx, discr); }; size_of, () {