Skip to content

Commit d0b315f

Browse files
committed
Fix try_read_value not working for enums
1 parent c6c0685 commit d0b315f

File tree

2 files changed

+37
-8
lines changed

2 files changed

+37
-8
lines changed

src/librustc_mir/interpret/eval_context.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,7 +1120,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
11201120

11211121
/// ensures this Value is not a ByRef
11221122
pub fn follow_by_ref_value(
1123-
&self,
1123+
&mut self,
11241124
value: Value,
11251125
ty: Ty<'tcx>,
11261126
) -> EvalResult<'tcx, Value> {
@@ -1133,7 +1133,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
11331133
}
11341134

11351135
pub fn value_to_scalar(
1136-
&self,
1136+
&mut self,
11371137
ValTy { value, ty } : ValTy<'tcx>,
11381138
) -> EvalResult<'tcx, Scalar> {
11391139
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
15401540
}
15411541
}
15421542

1543-
pub fn try_read_by_ref(&self, mut val: Value, ty: Ty<'tcx>) -> EvalResult<'tcx, Value> {
1543+
pub fn try_read_by_ref(&mut self, mut val: Value, ty: Ty<'tcx>) -> EvalResult<'tcx, Value> {
15441544
// Convert to ByVal or ScalarPair if possible
15451545
if let Value::ByRef(ptr, align) = val {
15461546
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
15501550
Ok(val)
15511551
}
15521552

1553-
pub fn try_read_value(&self, ptr: Scalar, ptr_align: Align, ty: Ty<'tcx>) -> EvalResult<'tcx, Option<Value>> {
1554-
let layout = self.layout_of(ty)?;
1553+
pub fn try_read_value(&mut self, ptr: Scalar, ptr_align: Align, ty: Ty<'tcx>) -> EvalResult<'tcx, Option<Value>> {
1554+
let mut layout = self.layout_of(ty)?;
15551555
self.memory.check_align(ptr, ptr_align)?;
15561556

15571557
if layout.size.bytes() == 0 {
@@ -1560,17 +1560,30 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
15601560

15611561
let ptr = ptr.to_ptr()?;
15621562

1563+
match layout.variants {
1564+
layout::Variants::NicheFilling { .. } |
1565+
layout::Variants::Tagged { .. } => {
1566+
let variant_index = self.read_discriminant_as_variant_index(
1567+
Place::from_ptr(ptr, ptr_align),
1568+
layout.ty,
1569+
)?;
1570+
layout = layout.for_variant(&self, variant_index);
1571+
trace!("variant layout: {:#?}", layout);
1572+
},
1573+
layout::Variants::Single { .. } => {},
1574+
}
1575+
15631576
match layout.abi {
15641577
layout::Abi::Scalar(..) => {
15651578
let scalar = self.memory.read_scalar(ptr, ptr_align, layout.size)?;
15661579
Ok(Some(Value::Scalar(scalar)))
15671580
}
15681581
layout::Abi::ScalarPair(ref a, ref b) => {
15691582
let (a, b) = (&a.value, &b.value);
1570-
let (a_size, b_size) = (a.size(self), b.size(self));
1583+
let (a_size, b_size) = (a.size(&self), b.size(&self));
15711584
let a_ptr = ptr;
1572-
let b_offset = a_size.abi_align(b.align(self));
1573-
let b_ptr = ptr.offset(b_offset, self)?.into();
1585+
let b_offset = a_size.abi_align(b.align(&self));
1586+
let b_ptr = ptr.offset(b_offset, &self)?.into();
15741587
let a_val = self.memory.read_scalar(a_ptr, ptr_align, a_size)?;
15751588
let b_val = self.memory.read_scalar(b_ptr, ptr_align, b_size)?;
15761589
Ok(Some(Value::ScalarPair(a_val, b_val)))
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-pass
12+
13+
const PARSE_BOOL: Option<&'static str> = None;
14+
static FOO: (Option<&str>, u32) = (PARSE_BOOL, 42);
15+
16+
fn main() {}

0 commit comments

Comments
 (0)