Skip to content

Commit 6eeedbc

Browse files
committed
generator fields are not necessarily initialized
1 parent 046e054 commit 6eeedbc

File tree

1 file changed

+22
-11
lines changed

1 file changed

+22
-11
lines changed

src/librustc_mir/interpret/visitor.rs

+22-11
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ macro_rules! make_value_visitor {
142142
self.walk_value(v)
143143
}
144144
/// Visit the given value as a union. No automatic recursion can happen here.
145+
/// Also called for the fields of a generator, which may or may not be initialized.
145146
#[inline(always)]
146147
fn visit_union(&mut self, _v: Self::V) -> EvalResult<'tcx>
147148
{
@@ -291,17 +292,28 @@ macro_rules! make_value_visitor {
291292
// use that as an unambiguous signal for detecting primitives. Make sure
292293
// we did not miss any primitive.
293294
debug_assert!(fields > 0);
294-
self.visit_union(v)?;
295+
self.visit_union(v)
295296
},
296297
layout::FieldPlacement::Arbitrary { ref offsets, .. } => {
297-
// FIXME: We collect in a vec because otherwise there are lifetime errors:
298-
// Projecting to a field needs (mutable!) access to `ecx`.
299-
let fields: Vec<EvalResult<'tcx, Self::V>> =
300-
(0..offsets.len()).map(|i| {
301-
v.project_field(self.ecx(), i as u64)
302-
})
303-
.collect();
304-
self.visit_aggregate(v, fields.into_iter())?;
298+
// Special handling needed for generators: All but the first field
299+
// (which is the state) are actually implicitly `MaybeUninit`, i.e.,
300+
// they may or may not be initialized, so we cannot visit them.
301+
match v.layout().ty.sty {
302+
ty::Generator(..) => {
303+
let field = v.project_field(self.ecx(), 0)?;
304+
self.visit_aggregate(v, std::iter::once(Ok(field)))
305+
}
306+
_ => {
307+
// FIXME: We collect in a vec because otherwise there are lifetime
308+
// errors: Projecting to a field needs access to `ecx`.
309+
let fields: Vec<EvalResult<'tcx, Self::V>> =
310+
(0..offsets.len()).map(|i| {
311+
v.project_field(self.ecx(), i as u64)
312+
})
313+
.collect();
314+
self.visit_aggregate(v, fields.into_iter())
315+
}
316+
}
305317
},
306318
layout::FieldPlacement::Array { .. } => {
307319
// Let's get an mplace first.
@@ -317,10 +329,9 @@ macro_rules! make_value_visitor {
317329
.map(|f| f.and_then(|f| {
318330
Ok(Value::from_mem_place(f))
319331
}));
320-
self.visit_aggregate(v, iter)?;
332+
self.visit_aggregate(v, iter)
321333
}
322334
}
323-
Ok(())
324335
}
325336
}
326337
}

0 commit comments

Comments
 (0)