Skip to content

Commit 33770ab

Browse files
committed
add visit() hook to the trait
1 parent fdc3a3e commit 33770ab

File tree

2 files changed

+23
-15
lines changed

2 files changed

+23
-15
lines changed

src/librustc_mir/interpret/validity.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,19 +207,19 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>
207207
}
208208

209209
#[inline]
210-
fn with_field(
210+
fn visit_field(
211211
&mut self,
212+
ectx: &mut EvalContext<'a, 'mir, 'tcx, M>,
212213
val: Self::V,
213214
field: usize,
214-
f: impl FnOnce(&mut Self) -> EvalResult<'tcx>,
215215
) -> EvalResult<'tcx> {
216216
// Remember the old state
217217
let path_len = self.path.len();
218218
let op = self.op;
219219
// Perform operation
220220
self.push_aggregate_field_path_elem(op.layout, field);
221221
self.op = val;
222-
f(self)?;
222+
self.visit(ectx)?;
223223
// Undo changes
224224
self.path.truncate(path_len);
225225
self.op = op;
@@ -596,6 +596,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
596596
};
597597

598598
// Run it
599-
self.visit_value(&mut visitor)
599+
visitor.visit(self)
600600
}
601601
}

src/librustc_mir/interpret/visitor.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
131131
}
132132

133133
// How to traverse a value and what to do when we are at the leaves.
134-
pub trait ValueVisitor<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>: fmt::Debug {
134+
pub trait ValueVisitor<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>: fmt::Debug + Sized {
135135
type V: Value<'a, 'mir, 'tcx, M>;
136136

137137
// There's a value in here.
@@ -143,16 +143,16 @@ pub trait ValueVisitor<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>: fmt::Debug {
143143
self.value().layout()
144144
}
145145

146-
// Replace the value by `val`, which must be the `field`th field of `self`,
147-
// then call `f` and then un-do everything that might have happened to the visitor state.
146+
// Replace the value by `val`, which must be the `field`th field of `self`, then call
147+
// `visit_value` and then un-do everything that might have happened to the visitor state.
148148
// The point of this is that some visitors keep a stack of fields that we projected below,
149149
// and this lets us avoid copying that stack; instead they will pop the stack after
150-
// executing `f`.
151-
fn with_field(
150+
// executing `visit_value`.
151+
fn visit_field(
152152
&mut self,
153+
ectx: &mut EvalContext<'a, 'mir, 'tcx, M>,
153154
val: Self::V,
154155
field: usize,
155-
f: impl FnOnce(&mut Self) -> EvalResult<'tcx>,
156156
) -> EvalResult<'tcx>;
157157

158158
// This is an enum, downcast it to whatever the current variant is.
@@ -170,6 +170,14 @@ pub trait ValueVisitor<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>: fmt::Debug {
170170
Ok(false)
171171
}
172172

173+
// Execute visitor on the current value. Used for recursing.
174+
#[inline]
175+
fn visit(&mut self, ectx: &mut EvalContext<'a, 'mir, 'tcx, M>)
176+
-> EvalResult<'tcx>
177+
{
178+
ectx.walk_value(self)
179+
}
180+
173181
// Actions on the leaves.
174182
fn visit_uninhabited(&mut self, ectx: &mut EvalContext<'a, 'mir, 'tcx, M>)
175183
-> EvalResult<'tcx>;
@@ -180,11 +188,11 @@ pub trait ValueVisitor<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>: fmt::Debug {
180188
}
181189

182190
impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
183-
pub fn visit_value<V: ValueVisitor<'a, 'mir, 'tcx, M>>(
191+
pub fn walk_value<V: ValueVisitor<'a, 'mir, 'tcx, M>>(
184192
&mut self,
185193
v: &mut V,
186194
) -> EvalResult<'tcx> {
187-
trace!("visit_value: {:?}", v);
195+
trace!("walk_value: {:?}", v);
188196

189197
// If this is a multi-variant layout, we have find the right one and proceed with that.
190198
// (No benefit from making this recursion, but it is equivalent to that.)
@@ -205,7 +213,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
205213
let dest = v.value().force_allocation(self)?;
206214
let inner = self.unpack_dyn_trait(dest)?.1;
207215
// recurse with the inner type
208-
return v.with_field(Value::from_mem_place(inner), 0, |v| self.visit_value(v));
216+
return v.visit_field(self, Value::from_mem_place(inner), 0);
209217
},
210218
_ => {},
211219
};
@@ -256,7 +264,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
256264
layout::FieldPlacement::Arbitrary { ref offsets, .. } => {
257265
for i in 0..offsets.len() {
258266
let val = v.value().project_field(self, i as u64)?;
259-
v.with_field(val, i, |v| self.visit_value(v))?;
267+
v.visit_field(self, val, i)?;
260268
}
261269
},
262270
layout::FieldPlacement::Array { .. } => {
@@ -272,7 +280,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
272280
};
273281
// Now iterate over it.
274282
for (i, field) in self.mplace_array_fields(mplace)?.enumerate() {
275-
v.with_field(Value::from_mem_place(field?), i, |v| self.visit_value(v))?;
283+
v.visit_field(self, Value::from_mem_place(field?), i)?;
276284
}
277285
}
278286
}

0 commit comments

Comments
 (0)