Skip to content

Commit b174b0b

Browse files
committed
miri-engine value visitor update to VariantIdx
1 parent 4a9ed3f commit b174b0b

File tree

3 files changed

+42
-10
lines changed

3 files changed

+42
-10
lines changed

src/librustc_mir/interpret/validity.rs

+26-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use std::hash::Hash;
1313
use std::ops::RangeInclusive;
1414

1515
use syntax_pos::symbol::Symbol;
16-
use rustc::ty::layout::{self, Size, Align, TyLayout, LayoutOf};
16+
use rustc::ty::layout::{self, Size, Align, TyLayout, LayoutOf, VariantIdx};
1717
use rustc::ty;
1818
use rustc_data_structures::fx::FxHashSet;
1919
use rustc::mir::interpret::{
@@ -74,6 +74,7 @@ macro_rules! try_validation {
7474
#[derive(Copy, Clone, Debug)]
7575
pub enum PathElem {
7676
Field(Symbol),
77+
Variant(Symbol),
7778
ClosureVar(Symbol),
7879
ArrayElem(usize),
7980
TupleElem(usize),
@@ -107,6 +108,7 @@ fn path_format(path: &Vec<PathElem>) -> String {
107108
for elem in path.iter() {
108109
match elem {
109110
Field(name) => write!(out, ".{}", name),
111+
Variant(name) => write!(out, ".<downcast-variant({})>", name),
110112
ClosureVar(name) => write!(out, ".<closure-var({})>", name),
111113
TupleElem(idx) => write!(out, ".{}", idx),
112114
ArrayElem(idx) => write!(out, "[{}]", idx),
@@ -192,9 +194,11 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> ValidityVisitor<'rt, 'a, '
192194
layout::Variants::Single { index } =>
193195
// Inside a variant
194196
PathElem::Field(def.variants[index].fields[field].ident.name),
195-
_ =>
196-
// To a variant
197-
PathElem::Field(def.variants[field].name)
197+
_ => {
198+
// Enums have no fields other than their tag
199+
assert_eq!(field, 0);
200+
PathElem::Tag
201+
}
198202
}
199203
}
200204

@@ -241,6 +245,24 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>
241245
Ok(())
242246
}
243247

248+
#[inline]
249+
fn visit_variant(
250+
&mut self,
251+
old_op: OpTy<'tcx, M::PointerTag>,
252+
variant_id: VariantIdx,
253+
new_op: OpTy<'tcx, M::PointerTag>
254+
) -> EvalResult<'tcx> {
255+
// Remember the old state
256+
let path_len = self.path.len();
257+
// Perform operation
258+
let name = old_op.layout.ty.ty_adt_def().unwrap().variants[variant_id].name;
259+
self.path.push(PathElem::Variant(name));
260+
self.visit_value(new_op)?;
261+
// Undo changes
262+
self.path.truncate(path_len);
263+
Ok(())
264+
}
265+
244266
#[inline]
245267
fn visit_value(&mut self, op: OpTy<'tcx, M::PointerTag>) -> EvalResult<'tcx>
246268
{

src/librustc_mir/interpret/visitor.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Visitor for a run-time value with a given layout: Traverse enums, structs and other compound
22
//! types until we arrive at the leaves, with custom handling for primitive types.
33
4-
use rustc::ty::layout::{self, TyLayout};
4+
use rustc::ty::layout::{self, TyLayout, VariantIdx};
55
use rustc::ty;
66
use rustc::mir::interpret::{
77
EvalResult,
@@ -32,7 +32,7 @@ pub trait Value<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>: Copy
3232
fn project_downcast(
3333
self,
3434
ecx: &EvalContext<'a, 'mir, 'tcx, M>,
35-
variant: usize,
35+
variant: VariantIdx,
3636
) -> EvalResult<'tcx, Self>;
3737

3838
/// Project to the n-th field.
@@ -70,7 +70,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
7070
fn project_downcast(
7171
self,
7272
ecx: &EvalContext<'a, 'mir, 'tcx, M>,
73-
variant: usize,
73+
variant: VariantIdx,
7474
) -> EvalResult<'tcx, Self> {
7575
ecx.operand_downcast(self, variant)
7676
}
@@ -109,7 +109,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
109109
fn project_downcast(
110110
self,
111111
ecx: &EvalContext<'a, 'mir, 'tcx, M>,
112-
variant: usize,
112+
variant: VariantIdx,
113113
) -> EvalResult<'tcx, Self> {
114114
ecx.mplace_downcast(self, variant)
115115
}
@@ -171,6 +171,16 @@ macro_rules! make_value_visitor {
171171
self.visit_value(new_val)
172172
}
173173

174+
#[inline(always)]
175+
fn visit_variant(
176+
&mut self,
177+
_old_val: Self::V,
178+
_variant: VariantIdx,
179+
new_val: Self::V,
180+
) -> EvalResult<'tcx> {
181+
self.visit_value(new_val)
182+
}
183+
174184
/// Called whenever we reach a value with uninhabited layout.
175185
/// Recursing to fields will *always* continue after this! This is not meant to control
176186
/// whether and how we descend recursively/ into the scalar's fields if there are any,
@@ -221,7 +231,7 @@ macro_rules! make_value_visitor {
221231
let inner = v.project_downcast(self.ecx(), idx)?;
222232
trace!("walk_value: variant layout: {:#?}", inner.layout());
223233
// recurse with the inner type
224-
return self.visit_field(v, idx, inner);
234+
return self.visit_variant(v, idx, inner);
225235
}
226236
layout::Variants::Single { .. } => {}
227237
}

src/test/ui/consts/const-eval/ub-enum.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ error[E0080]: it is undefined behavior to use this value
4242
--> $DIR/ub-enum.rs:61:1
4343
|
4444
LL | const BAD_ENUM_CHAR: Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));
45-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 4294967295 at .Some.0.1, but expected something less or equal to 1114111
45+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 4294967295 at .<downcast-variant(Some)>.0.1, but expected something less or equal to 1114111
4646
|
4747
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
4848

0 commit comments

Comments
 (0)