Fix try_read_value
not working for enums
This commit is contained in:
parent
c6c06854c0
commit
d0b315f262
@ -1120,7 +1120,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
|||||||
|
|
||||||
/// ensures this Value is not a ByRef
|
/// ensures this Value is not a ByRef
|
||||||
pub fn follow_by_ref_value(
|
pub fn follow_by_ref_value(
|
||||||
&self,
|
&mut self,
|
||||||
value: Value,
|
value: Value,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
) -> EvalResult<'tcx, Value> {
|
) -> EvalResult<'tcx, Value> {
|
||||||
@ -1133,7 +1133,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn value_to_scalar(
|
pub fn value_to_scalar(
|
||||||
&self,
|
&mut self,
|
||||||
ValTy { value, ty } : ValTy<'tcx>,
|
ValTy { value, ty } : ValTy<'tcx>,
|
||||||
) -> EvalResult<'tcx, Scalar> {
|
) -> EvalResult<'tcx, Scalar> {
|
||||||
match self.follow_by_ref_value(value, ty)? {
|
match self.follow_by_ref_value(value, ty)? {
|
||||||
@ -1540,7 +1540,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_read_by_ref(&self, mut val: Value, ty: Ty<'tcx>) -> EvalResult<'tcx, Value> {
|
pub fn try_read_by_ref(&mut self, mut val: Value, ty: Ty<'tcx>) -> EvalResult<'tcx, Value> {
|
||||||
// Convert to ByVal or ScalarPair if possible
|
// Convert to ByVal or ScalarPair if possible
|
||||||
if let Value::ByRef(ptr, align) = val {
|
if let Value::ByRef(ptr, align) = val {
|
||||||
if let Some(read_val) = self.try_read_value(ptr, align, ty)? {
|
if let Some(read_val) = self.try_read_value(ptr, align, ty)? {
|
||||||
@ -1550,8 +1550,8 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
|||||||
Ok(val)
|
Ok(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_read_value(&self, ptr: Scalar, ptr_align: Align, ty: Ty<'tcx>) -> EvalResult<'tcx, Option<Value>> {
|
pub fn try_read_value(&mut self, ptr: Scalar, ptr_align: Align, ty: Ty<'tcx>) -> EvalResult<'tcx, Option<Value>> {
|
||||||
let layout = self.layout_of(ty)?;
|
let mut layout = self.layout_of(ty)?;
|
||||||
self.memory.check_align(ptr, ptr_align)?;
|
self.memory.check_align(ptr, ptr_align)?;
|
||||||
|
|
||||||
if layout.size.bytes() == 0 {
|
if layout.size.bytes() == 0 {
|
||||||
@ -1560,6 +1560,19 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
|||||||
|
|
||||||
let ptr = ptr.to_ptr()?;
|
let ptr = ptr.to_ptr()?;
|
||||||
|
|
||||||
|
match layout.variants {
|
||||||
|
layout::Variants::NicheFilling { .. } |
|
||||||
|
layout::Variants::Tagged { .. } => {
|
||||||
|
let variant_index = self.read_discriminant_as_variant_index(
|
||||||
|
Place::from_ptr(ptr, ptr_align),
|
||||||
|
layout.ty,
|
||||||
|
)?;
|
||||||
|
layout = layout.for_variant(&self, variant_index);
|
||||||
|
trace!("variant layout: {:#?}", layout);
|
||||||
|
},
|
||||||
|
layout::Variants::Single { .. } => {},
|
||||||
|
}
|
||||||
|
|
||||||
match layout.abi {
|
match layout.abi {
|
||||||
layout::Abi::Scalar(..) => {
|
layout::Abi::Scalar(..) => {
|
||||||
let scalar = self.memory.read_scalar(ptr, ptr_align, layout.size)?;
|
let scalar = self.memory.read_scalar(ptr, ptr_align, layout.size)?;
|
||||||
@ -1567,10 +1580,10 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
|||||||
}
|
}
|
||||||
layout::Abi::ScalarPair(ref a, ref b) => {
|
layout::Abi::ScalarPair(ref a, ref b) => {
|
||||||
let (a, b) = (&a.value, &b.value);
|
let (a, b) = (&a.value, &b.value);
|
||||||
let (a_size, b_size) = (a.size(self), b.size(self));
|
let (a_size, b_size) = (a.size(&self), b.size(&self));
|
||||||
let a_ptr = ptr;
|
let a_ptr = ptr;
|
||||||
let b_offset = a_size.abi_align(b.align(self));
|
let b_offset = a_size.abi_align(b.align(&self));
|
||||||
let b_ptr = ptr.offset(b_offset, self)?.into();
|
let b_ptr = ptr.offset(b_offset, &self)?.into();
|
||||||
let a_val = self.memory.read_scalar(a_ptr, ptr_align, a_size)?;
|
let a_val = self.memory.read_scalar(a_ptr, ptr_align, a_size)?;
|
||||||
let b_val = self.memory.read_scalar(b_ptr, ptr_align, b_size)?;
|
let b_val = self.memory.read_scalar(b_ptr, ptr_align, b_size)?;
|
||||||
Ok(Some(Value::ScalarPair(a_val, b_val)))
|
Ok(Some(Value::ScalarPair(a_val, b_val)))
|
||||||
|
16
src/test/ui/const-eval/simple_with_undef.rs
Normal file
16
src/test/ui/const-eval/simple_with_undef.rs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// compile-pass
|
||||||
|
|
||||||
|
const PARSE_BOOL: Option<&'static str> = None;
|
||||||
|
static FOO: (Option<&str>, u32) = (PARSE_BOOL, 42);
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Reference in New Issue
Block a user