X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustc_mir%2Finterpret%2Foperand.rs;h=06b7206f4292c8aca5edbdfd9581d868a98beee6;hb=e9c41148c0c834d13d6f45bfd99c8f23781c5d31;hp=7a545e8ad6f792abbee4190061bf46eed0ac56fd;hpb=3f7e7c2fd3dc5646067564da62533dc70540a460;p=rust.git diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 7a545e8ad6f..06b7206f429 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -472,39 +472,37 @@ pub fn place_to_op( // avoid allocations. pub(super) fn eval_place_to_op( &self, - mir_place: &mir::Place<'tcx>, + place: &mir::Place<'tcx>, layout: Option>, ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { use rustc::mir::PlaceBase; - mir_place.iterate(|place_base, place_projection| { - let mut op = match place_base { - PlaceBase::Local(mir::RETURN_PLACE) => - throw_unsup!(ReadFromReturnPointer), - PlaceBase::Local(local) => { - // Do not use the layout passed in as argument if the base we are looking at - // here is not the entire place. - // FIXME use place_projection.is_empty() when is available - let layout = if mir_place.projection.is_none() { - layout - } else { - None - }; - - self.access_local(self.frame(), *local, layout)? - } - PlaceBase::Static(place_static) => { - self.eval_static_to_mplace(place_static)?.into() - } - }; + let mut op = match &place.base { + PlaceBase::Local(mir::RETURN_PLACE) => + throw_unsup!(ReadFromReturnPointer), + PlaceBase::Local(local) => { + // Do not use the layout passed in as argument if the base we are looking at + // here is not the entire place. + // FIXME use place_projection.is_empty() when is available + let layout = if place.projection.is_empty() { + layout + } else { + None + }; - for proj in place_projection { - op = self.operand_projection(op, &proj.elem)? + self.access_local(self.frame(), *local, layout)? + } + PlaceBase::Static(place_static) => { + self.eval_static_to_mplace(&place_static)?.into() } + }; - trace!("eval_place_to_op: got {:?}", *op); - Ok(op) - }) + for elem in place.projection.iter() { + op = self.operand_projection(op, elem)? + } + + trace!("eval_place_to_op: got {:?}", *op); + Ok(op) } /// Evaluate the operand, returning a place where you can then find the data. @@ -629,11 +627,10 @@ pub fn read_discriminant( // post-process Ok(match *discr_kind { layout::DiscriminantKind::Tag => { - let bits_discr = match raw_discr.to_bits(discr_val.layout.size) { - Ok(raw_discr) => raw_discr, - Err(_) => - throw_unsup!(InvalidDiscriminant(raw_discr.erase_tag())), - }; + let bits_discr = raw_discr + .not_undef() + .and_then(|raw_discr| self.force_bits(raw_discr, discr_val.layout.size)) + .map_err(|_| err_unsup!(InvalidDiscriminant(raw_discr.erase_tag())))?; let real_discr = if discr_val.layout.ty.is_signed() { // going from layout tag type to typeck discriminant type // requires first sign extending with the layout discriminant