about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2018-11-20 16:19:24 +0100
committerRalf Jung <post@ralfj.de>2018-11-20 16:19:43 +0100
commit6befe6784f37d953884ef05982b41c3a11932170 (patch)
treeeecb06765edeaaed6acd366cadda530f3135468e /src
parent7f1077700c019b2dc8d651528ecad106c9267858 (diff)
downloadrust-6befe6784f37d953884ef05982b41c3a11932170.tar.gz
rust-6befe6784f37d953884ef05982b41c3a11932170.zip
treat generator fields like unions
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/interpret/visitor.rs24
1 files changed, 22 insertions, 2 deletions
diff --git a/src/librustc_mir/interpret/visitor.rs b/src/librustc_mir/interpret/visitor.rs
index a645e067322..81e56f3115d 100644
--- a/src/librustc_mir/interpret/visitor.rs
+++ b/src/librustc_mir/interpret/visitor.rs
@@ -158,7 +158,9 @@ macro_rules! make_value_visitor {
             ) -> EvalResult<'tcx> {
                 self.walk_aggregate(v, fields)
             }
-            /// Called each time we recurse down to a field, passing in old and new value.
+
+            /// Called each time we recurse down to a field of a "product-like" aggregate
+            /// (structs, tuples, arrays and the like, but not enums), passing in old and new value.
             /// This gives the visitor the chance to track the stack of nested fields that
             /// we are descending through.
             #[inline(always)]
@@ -171,6 +173,19 @@ macro_rules! make_value_visitor {
                 self.visit_value(new_val)
             }
 
+            /// Called for recursing into the field of a generator.  These are not known to be
+            /// initialized, so we treat them like unions.
+            #[inline(always)]
+            fn visit_generator_field(
+                &mut self,
+                _old_val: Self::V,
+                _field: usize,
+                new_val: Self::V,
+            ) -> EvalResult<'tcx> {
+                self.visit_union(new_val)
+            }
+
+            /// Called when recursing into an enum variant.
             #[inline(always)]
             fn visit_variant(
                 &mut self,
@@ -300,7 +315,12 @@ macro_rules! make_value_visitor {
                         match v.layout().ty.sty {
                             ty::Generator(..) => {
                                 let field = v.project_field(self.ecx(), 0)?;
-                                self.visit_aggregate(v, std::iter::once(Ok(field)))
+                                self.visit_aggregate(v, std::iter::once(Ok(field)))?;
+                                for i in 1..offsets.len() {
+                                    let field = v.project_field(self.ecx(), i as u64)?;
+                                    self.visit_generator_field(v, i, field)?;
+                                }
+                                Ok(())
                             }
                             _ => {
                                 // FIXME: We collect in a vec because otherwise there are lifetime