about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2018-05-02 10:17:12 +0200
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2018-05-08 16:21:58 +0200
commit0edc8f4270589002fe12b9de9a2bd2b1220feb4d (patch)
tree2069b31875e8bad17b80e860354dddf1d4ac94e6
parent697a989ec05ad7445bacd68983fd807e159ea717 (diff)
downloadrust-0edc8f4270589002fe12b9de9a2bd2b1220feb4d.tar.gz
rust-0edc8f4270589002fe12b9de9a2bd2b1220feb4d.zip
Store generator movability outside GeneratorInterior
-rw-r--r--src/librustc/ich/impls_mir.rs3
-rw-r--r--src/librustc/ich/impls_ty.rs5
-rw-r--r--src/librustc/mir/mod.rs11
-rw-r--r--src/librustc/mir/tcx.rs4
-rw-r--r--src/librustc/mir/visit.rs5
-rw-r--r--src/librustc/traits/select.rs4
-rw-r--r--src/librustc/ty/context.rs5
-rw-r--r--src/librustc/ty/fast_reject.rs2
-rw-r--r--src/librustc/ty/flags.rs2
-rw-r--r--src/librustc/ty/item_path.rs2
-rw-r--r--src/librustc/ty/layout.rs4
-rw-r--r--src/librustc/ty/outlives.rs2
-rw-r--r--src/librustc/ty/relate.rs9
-rw-r--r--src/librustc/ty/structural_impls.rs14
-rw-r--r--src/librustc/ty/sty.rs5
-rw-r--r--src/librustc/ty/util.rs2
-rw-r--r--src/librustc/ty/walk.rs2
-rw-r--r--src/librustc/util/ppaux.rs4
-rw-r--r--src/librustc_mir/borrow_check/error_reporting.rs2
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/annotation.rs2
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs6
-rw-r--r--src/librustc_mir/borrow_check/nll/universal_regions.rs19
-rw-r--r--src/librustc_mir/build/expr/as_rvalue.rs7
-rw-r--r--src/librustc_mir/hair/cx/expr.rs4
-rw-r--r--src/librustc_mir/hair/mod.rs2
-rw-r--r--src/librustc_mir/monomorphize/item.rs2
-rw-r--r--src/librustc_mir/shim.rs2
-rw-r--r--src/librustc_mir/transform/check_unsafety.rs2
-rw-r--r--src/librustc_mir/transform/generator.rs19
-rw-r--r--src/librustc_mir/util/elaborate_drops.rs2
-rw-r--r--src/librustc_mir/util/pretty.rs3
-rw-r--r--src/librustc_traits/dropck_outlives.rs2
-rw-r--r--src/librustc_trans/common.rs2
-rw-r--r--src/librustc_trans/debuginfo/metadata.rs2
-rw-r--r--src/librustc_trans/mir/mod.rs2
-rw-r--r--src/librustc_typeck/check/closure.rs4
-rw-r--r--src/librustc_typeck/check/mod.rs16
-rw-r--r--src/librustc_typeck/check/upvar.rs3
38 files changed, 108 insertions, 80 deletions
diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs
index 33f43e53394..29a0632511c 100644
--- a/src/librustc/ich/impls_mir.rs
+++ b/src/librustc/ich/impls_mir.rs
@@ -483,10 +483,11 @@ for mir::AggregateKind<'gcx> {
                 def_id.hash_stable(hcx, hasher);
                 substs.hash_stable(hcx, hasher);
             }
-            mir::AggregateKind::Generator(def_id, ref substs, ref interior) => {
+            mir::AggregateKind::Generator(def_id, ref substs, ref interior, movability) => {
                 def_id.hash_stable(hcx, hasher);
                 substs.hash_stable(hcx, hasher);
                 interior.hash_stable(hcx, hasher);
+                movability.hash_stable(hcx, hasher);
             }
         }
     }
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index a40d8e09277..96ef8591645 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -518,7 +518,7 @@ for ::middle::const_val::ErrKind<'gcx> {
 
 impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs });
 
-impl_stable_hash_for!(struct ty::GeneratorInterior<'tcx> { witness, movable });
+impl_stable_hash_for!(struct ty::GeneratorInterior<'tcx> { witness });
 
 impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> {
     parent,
@@ -908,10 +908,11 @@ for ty::TypeVariants<'gcx>
                 def_id.hash_stable(hcx, hasher);
                 closure_substs.hash_stable(hcx, hasher);
             }
-            TyGenerator(def_id, closure_substs, interior) => {
+            TyGenerator(def_id, closure_substs, interior, movability) => {
                 def_id.hash_stable(hcx, hasher);
                 closure_substs.hash_stable(hcx, hasher);
                 interior.hash_stable(hcx, hasher);
+                movability.hash_stable(hcx, hasher);
             }
             TyGeneratorWitness(types) => {
                 types.hash_stable(hcx, hasher)
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 37f6d47ff84..907ffc67606 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -1641,7 +1641,7 @@ pub enum AggregateKind<'tcx> {
     Adt(&'tcx AdtDef, usize, &'tcx Substs<'tcx>, Option<usize>),
 
     Closure(DefId, ClosureSubsts<'tcx>),
-    Generator(DefId, ClosureSubsts<'tcx>, GeneratorInterior<'tcx>),
+    Generator(DefId, ClosureSubsts<'tcx>, GeneratorInterior<'tcx>, hir::GeneratorMovability),
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
@@ -1804,7 +1804,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
                         }
                     }),
 
-                    AggregateKind::Generator(def_id, _, _) => ty::tls::with(|tcx| {
+                    AggregateKind::Generator(def_id, _, _, _) => ty::tls::with(|tcx| {
                         if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
                             let name = format!("[generator@{:?}]", tcx.hir.span(node_id));
                             let mut struct_fmt = fmt.debug_struct(&name);
@@ -2375,10 +2375,11 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
                         AggregateKind::Adt(def, v, substs.fold_with(folder), n),
                     AggregateKind::Closure(id, substs) =>
                         AggregateKind::Closure(id, substs.fold_with(folder)),
-                    AggregateKind::Generator(id, substs, interior) =>
+                    AggregateKind::Generator(id, substs, interior, movablity) =>
                         AggregateKind::Generator(id,
                                                  substs.fold_with(folder),
-                                                 interior.fold_with(folder)),
+                                                 interior.fold_with(folder),
+                                                 movablity),
                 };
                 Aggregate(kind, fields.fold_with(folder))
             }
@@ -2405,7 +2406,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
                     AggregateKind::Tuple => false,
                     AggregateKind::Adt(_, _, substs, _) => substs.visit_with(visitor),
                     AggregateKind::Closure(_, substs) => substs.visit_with(visitor),
-                    AggregateKind::Generator(_, substs, interior) => substs.visit_with(visitor) ||
+                    AggregateKind::Generator(_, substs, interior, _) => substs.visit_with(visitor) ||
                         interior.visit_with(visitor),
                 }) || fields.visit_with(visitor)
             }
diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs
index 20902d91110..33af199d758 100644
--- a/src/librustc/mir/tcx.rs
+++ b/src/librustc/mir/tcx.rs
@@ -186,8 +186,8 @@ impl<'tcx> Rvalue<'tcx> {
                     AggregateKind::Closure(did, substs) => {
                         tcx.mk_closure_from_closure_substs(did, substs)
                     }
-                    AggregateKind::Generator(did, substs, interior) => {
-                        tcx.mk_generator(did, substs, interior)
+                    AggregateKind::Generator(did, substs, interior, movability) => {
+                        tcx.mk_generator(did, substs, interior, movability)
                     }
                 }
             }
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index 59b6f369754..6aed5076c1f 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -595,8 +595,9 @@ macro_rules! make_mir_visitor {
                                 self.visit_closure_substs(closure_substs, location);
                             }
                             AggregateKind::Generator(ref $($mutability)* def_id,
-                                                   ref $($mutability)* closure_substs,
-                                                   ref $($mutability)* interior) => {
+                                                     ref $($mutability)* closure_substs,
+                                                     ref $($mutability)* interior,
+                                                     _movability) => {
                                 self.visit_def_id(def_id, location);
                                 self.visit_closure_substs(closure_substs, location);
                                 self.visit_generator_interior(interior, location);
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 54b2cf28082..82643c315b9 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -2280,7 +2280,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                 substs.upvar_tys(def_id, self.tcx()).collect()
             }
 
-            ty::TyGenerator(def_id, ref substs, interior) => {
+            ty::TyGenerator(def_id, ref substs, interior, _) => {
                 substs.upvar_tys(def_id, self.tcx()).chain(iter::once(interior.witness)).collect()
             }
 
@@ -2756,7 +2756,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
         // type/region parameters
         let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
         let (closure_def_id, substs) = match self_ty.sty {
-            ty::TyGenerator(id, substs, _) => (id, substs),
+            ty::TyGenerator(id, substs, _, _) => (id, substs),
             _ => bug!("closure candidate for non-closure {:?}", obligation)
         };
 
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 3d154e43a9a..6ed243361c0 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -2453,9 +2453,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     pub fn mk_generator(self,
                         id: DefId,
                         closure_substs: ClosureSubsts<'tcx>,
-                        interior: GeneratorInterior<'tcx>)
+                        interior: GeneratorInterior<'tcx>,
+                        movability: hir::GeneratorMovability)
                         -> Ty<'tcx> {
-        self.mk_ty(TyGenerator(id, closure_substs, interior))
+        self.mk_ty(TyGenerator(id, closure_substs, interior, movability))
     }
 
     pub fn mk_generator_witness(self, types: ty::Binder<&'tcx Slice<Ty<'tcx>>>) -> Ty<'tcx> {
diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs
index 31b3ca44700..2b6901f74de 100644
--- a/src/librustc/ty/fast_reject.rs
+++ b/src/librustc/ty/fast_reject.rs
@@ -90,7 +90,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
         ty::TyClosure(def_id, _) => {
             Some(ClosureSimplifiedType(def_id))
         }
-        ty::TyGenerator(def_id, _, _) => {
+        ty::TyGenerator(def_id, _, _, _) => {
             Some(GeneratorSimplifiedType(def_id))
         }
         ty::TyGeneratorWitness(ref tys) => {
diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs
index 086fc66c70f..acc17a08a80 100644
--- a/src/librustc/ty/flags.rs
+++ b/src/librustc/ty/flags.rs
@@ -87,7 +87,7 @@ impl FlagComputation {
                 }
             }
 
-            &ty::TyGenerator(_, ref substs, ref interior) => {
+            &ty::TyGenerator(_, ref substs, ref interior, _) => {
                 self.add_flags(TypeFlags::HAS_TY_CLOSURE);
                 self.add_flags(TypeFlags::HAS_LOCAL_NAMES);
                 self.add_substs(&substs.substs);
diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs
index 752b7f69a6a..b58c4138597 100644
--- a/src/librustc/ty/item_path.rs
+++ b/src/librustc/ty/item_path.rs
@@ -369,7 +369,7 @@ pub fn characteristic_def_id_of_type(ty: Ty) -> Option<DefId> {
 
         ty::TyFnDef(def_id, _) |
         ty::TyClosure(def_id, _) |
-        ty::TyGenerator(def_id, _, _) |
+        ty::TyGenerator(def_id, _, _, _) |
         ty::TyForeign(def_id) => Some(def_id),
 
         ty::TyBool |
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 02c4b73efa1..7b91040b8e7 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -599,7 +599,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
             }
 
             // Tuples, generators and closures.
-            ty::TyGenerator(def_id, ref substs, _) => {
+            ty::TyGenerator(def_id, ref substs, _, _) => {
                 let tys = substs.field_tys(def_id, tcx);
                 univariant(&tys.map(|ty| self.layout_of(ty)).collect::<Result<Vec<_>, _>>()?,
                     &ReprOptions::default(),
@@ -1603,7 +1603,7 @@ impl<'a, 'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx>
                 substs.upvar_tys(def_id, tcx).nth(i).unwrap()
             }
 
-            ty::TyGenerator(def_id, ref substs, _) => {
+            ty::TyGenerator(def_id, ref substs, _, _) => {
                 substs.field_tys(def_id, tcx).nth(i).unwrap()
             }
 
diff --git a/src/librustc/ty/outlives.rs b/src/librustc/ty/outlives.rs
index ff99a4b7ff6..4eb736789f3 100644
--- a/src/librustc/ty/outlives.rs
+++ b/src/librustc/ty/outlives.rs
@@ -79,7 +79,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                 }
             }
 
-            ty::TyGenerator(def_id, ref substs, _) => {
+            ty::TyGenerator(def_id, ref substs, _, _) => {
                 // Same as the closure case
                 for upvar_ty in substs.upvar_tys(def_id, *self) {
                     self.compute_components(upvar_ty, out);
diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs
index 03ed6e7ac90..ed0835418a4 100644
--- a/src/librustc/ty/relate.rs
+++ b/src/librustc/ty/relate.rs
@@ -415,8 +415,8 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
             Ok(tcx.mk_dynamic(relation.relate(a_obj, b_obj)?, region_bound))
         }
 
-        (&ty::TyGenerator(a_id, a_substs, a_interior),
-         &ty::TyGenerator(b_id, b_substs, b_interior))
+        (&ty::TyGenerator(a_id, a_substs, a_interior, movability),
+         &ty::TyGenerator(b_id, b_substs, b_interior, _))
             if a_id == b_id =>
         {
             // All TyGenerator types with the same id represent
@@ -424,7 +424,7 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
             // all of their regions should be equated.
             let substs = relation.relate(&a_substs, &b_substs)?;
             let interior = relation.relate(&a_interior, &b_interior)?;
-            Ok(tcx.mk_generator(a_id, substs, interior))
+            Ok(tcx.mk_generator(a_id, substs, interior, movability))
         }
 
         (&ty::TyGeneratorWitness(a_types), &ty::TyGeneratorWitness(b_types)) =>
@@ -618,9 +618,8 @@ impl<'tcx> Relate<'tcx> for ty::GeneratorInterior<'tcx> {
                            -> RelateResult<'tcx, ty::GeneratorInterior<'tcx>>
         where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
     {
-        assert_eq!(a.movable, b.movable);
         let witness = relation.relate(&a.witness, &b.witness)?;
-        Ok(ty::GeneratorInterior { witness, movable: a.movable })
+        Ok(ty::GeneratorInterior { witness })
     }
 }
 
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index d4ed6c60e0e..6df3b5dc2bd 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -313,7 +313,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::GeneratorInterior<'a> {
     type Lifted = ty::GeneratorInterior<'tcx>;
     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&self.witness).map(|witness| {
-            ty::GeneratorInterior { witness, movable: self.movable }
+            ty::GeneratorInterior { witness }
         })
     }
 }
@@ -867,8 +867,12 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
             ty::TyRef(ref r, tm) => {
                 ty::TyRef(r.fold_with(folder), tm.fold_with(folder))
             }
-            ty::TyGenerator(did, substs, interior) => {
-                ty::TyGenerator(did, substs.fold_with(folder), interior.fold_with(folder))
+            ty::TyGenerator(did, substs, interior, movability) => {
+                ty::TyGenerator(
+                    did,
+                    substs.fold_with(folder),
+                    interior.fold_with(folder),
+                    movability)
             }
             ty::TyGeneratorWitness(types) => ty::TyGeneratorWitness(types.fold_with(folder)),
             ty::TyClosure(did, substs) => ty::TyClosure(did, substs.fold_with(folder)),
@@ -902,7 +906,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
             ty::TyFnDef(_, substs) => substs.visit_with(visitor),
             ty::TyFnPtr(ref f) => f.visit_with(visitor),
             ty::TyRef(r, ref tm) => r.visit_with(visitor) || tm.visit_with(visitor),
-            ty::TyGenerator(_did, ref substs, ref interior) => {
+            ty::TyGenerator(_did, ref substs, ref interior, _) => {
                 substs.visit_with(visitor) || interior.visit_with(visitor)
             }
             ty::TyGeneratorWitness(ref types) => types.visit_with(visitor),
@@ -981,7 +985,7 @@ BraceStructTypeFoldableImpl! {
 
 BraceStructTypeFoldableImpl! {
     impl<'tcx> TypeFoldable<'tcx> for ty::GeneratorInterior<'tcx> {
-        witness, movable,
+        witness,
     }
 }
 
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 382db571b52..b2c715bf7b9 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -139,7 +139,7 @@ pub enum TypeVariants<'tcx> {
 
     /// The anonymous type of a generator. Used to represent the type of
     /// `|a| yield a`.
-    TyGenerator(DefId, ClosureSubsts<'tcx>, GeneratorInterior<'tcx>),
+    TyGenerator(DefId, ClosureSubsts<'tcx>, GeneratorInterior<'tcx>, hir::GeneratorMovability),
 
     /// A type representin the types stored inside a generator.
     /// This should only appear in GeneratorInteriors.
@@ -420,7 +420,6 @@ impl<'a, 'gcx, 'tcx> ClosureSubsts<'tcx> {
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
 pub struct GeneratorInterior<'tcx> {
     pub witness: Ty<'tcx>,
-    pub movable: bool,
 }
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
@@ -1605,7 +1604,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
             TyAdt(_, substs) | TyAnon(_, substs) => {
                 substs.regions().collect()
             }
-            TyClosure(_, ref substs) | TyGenerator(_, ref substs, _) => {
+            TyClosure(_, ref substs) | TyGenerator(_, ref substs, _, _) => {
                 substs.substs.regions().collect()
             }
             TyProjection(ref data) => {
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 4aa70e1f7e0..12421715ed5 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -667,7 +667,7 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W>
             TyRawPtr(m) |
             TyRef(_, m) => self.hash(m.mutbl),
             TyClosure(def_id, _) |
-            TyGenerator(def_id, _, _) |
+            TyGenerator(def_id, _, _, _) |
             TyAnon(def_id, _) |
             TyFnDef(def_id, _) => self.def_id(def_id),
             TyAdt(d, _) => self.def_id(d.did),
diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs
index 46c048e839b..d3fa376d6a8 100644
--- a/src/librustc/ty/walk.rs
+++ b/src/librustc/ty/walk.rs
@@ -118,7 +118,7 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
         ty::TyClosure(_, ref substs) => {
             stack.extend(substs.substs.types().rev());
         }
-        ty::TyGenerator(_, ref substs, ref interior) => {
+        ty::TyGenerator(_, ref substs, ref interior, _) => {
             stack.push(interior.witness);
             stack.extend(substs.substs.types().rev());
         }
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 894a18b79cc..770357e549d 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -1110,9 +1110,9 @@ define_print! {
                     })
                 }
                 TyStr => write!(f, "str"),
-                TyGenerator(did, substs, interior) => ty::tls::with(|tcx| {
+                TyGenerator(did, substs, interior, movability) => ty::tls::with(|tcx| {
                     let upvar_tys = substs.upvar_tys(did, tcx);
-                    if interior.movable {
+                    if movability == hir::GeneratorMovability::Movable {
                         write!(f, "[generator")?;
                     } else {
                         write!(f, "[static generator")?;
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index db2e078586e..f68c164751d 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -777,7 +777,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                     self.describe_field_from_ty(&tnm.ty, field)
                 }
                 ty::TyArray(ty, _) | ty::TySlice(ty) => self.describe_field_from_ty(&ty, field),
-                ty::TyClosure(def_id, _) | ty::TyGenerator(def_id, _, _) => {
+                ty::TyClosure(def_id, _) | ty::TyGenerator(def_id, _, _, _) => {
                     // Convert the def-id into a node-id. node-ids are only valid for
                     // the local code in the current crate, so this returns an `Option` in case
                     // the closure comes from another crate. But in that case we wouldn't
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/annotation.rs b/src/librustc_mir/borrow_check/nll/region_infer/annotation.rs
index d213f376d2b..664d4214ca8 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/annotation.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/annotation.rs
@@ -30,7 +30,7 @@ impl<'gcx, 'tcx> RegionInferenceContext<'tcx> {
                     &substs.substs[..]
                 ));
             }
-            DefiningTy::Generator(def_id, substs, interior) => {
+            DefiningTy::Generator(def_id, substs, interior, _) => {
                 err.note(&format!(
                     "defining type: {:?} with closure substs {:#?} and interior {:?}",
                     def_id,
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 42a1745addf..6c4c4a171ef 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -528,7 +528,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
                         }),
                     }
                 }
-                ty::TyGenerator(def_id, substs, _) => {
+                ty::TyGenerator(def_id, substs, _, _) => {
                     // Try pre-transform fields first (upvars and current state)
                     if let Some(ty) = substs.pre_transforms_tys(def_id, tcx).nth(field.index()) {
                         return Ok(ty);
@@ -1254,7 +1254,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                     }),
                 }
             }
-            AggregateKind::Generator(def_id, substs, _) => {
+            AggregateKind::Generator(def_id, substs, _, _) => {
                 // Try pre-transform fields first (upvars and current state)
                 if let Some(ty) = substs.pre_transforms_tys(def_id, tcx).nth(field_index) {
                     Ok(ty)
@@ -1497,7 +1497,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                 tcx.predicates_of(*def_id).instantiate(tcx, substs.substs)
             }
 
-            AggregateKind::Generator(def_id, substs, _) => {
+            AggregateKind::Generator(def_id, substs, _, _) => {
                 tcx.predicates_of(*def_id).instantiate(tcx, substs.substs)
             }
 
diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs
index 0fe6265345d..0e519a37e57 100644
--- a/src/librustc_mir/borrow_check/nll/universal_regions.rs
+++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs
@@ -22,7 +22,7 @@
 //! The code in this file doesn't *do anything* with those results; it
 //! just returns them for other code to use.
 
-use rustc::hir::{BodyOwnerKind, HirId};
+use rustc::hir::{self, BodyOwnerKind, HirId};
 use rustc::hir::def_id::DefId;
 use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
 use rustc::infer::region_constraints::GenericKind;
@@ -116,7 +116,10 @@ pub enum DefiningTy<'tcx> {
     /// The MIR is a generator. The signature is that generators take
     /// no parameters and return the result of
     /// `ClosureSubsts::generator_return_ty`.
-    Generator(DefId, ty::ClosureSubsts<'tcx>, ty::GeneratorInterior<'tcx>),
+    Generator(DefId,
+              ty::ClosureSubsts<'tcx>,
+              ty::GeneratorInterior<'tcx>,
+              hir::GeneratorMovability),
 
     /// The MIR is a fn item with the given def-id and substs. The signature
     /// of the function can be bound then with the `fn_sig` query.
@@ -508,7 +511,7 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> {
         );
 
         let yield_ty = match defining_ty {
-            DefiningTy::Generator(def_id, substs, _) => {
+            DefiningTy::Generator(def_id, substs, _, _) => {
                 Some(substs.generator_yield_ty(def_id, self.infcx.tcx))
             }
             _ => None,
@@ -550,8 +553,8 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> {
 
                 match defining_ty.sty  {
                     ty::TyClosure(def_id, substs) => DefiningTy::Closure(def_id, substs),
-                    ty::TyGenerator(def_id, substs, interior) => {
-                        DefiningTy::Generator(def_id, substs, interior)
+                    ty::TyGenerator(def_id, substs, interior, movability) => {
+                        DefiningTy::Generator(def_id, substs, interior, movability)
                     }
                     ty::TyFnDef(def_id, substs) => DefiningTy::FnDef(def_id, substs),
                     _ => span_bug!(
@@ -587,7 +590,7 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> {
         let closure_base_def_id = tcx.closure_base_def_id(self.mir_def_id);
         let identity_substs = Substs::identity_for_item(gcx, closure_base_def_id);
         let fr_substs = match defining_ty {
-            DefiningTy::Closure(_, substs) | DefiningTy::Generator(_, substs, _) => {
+            DefiningTy::Closure(_, substs) | DefiningTy::Generator(_, substs, _, _) => {
                 // In the case of closures, we rely on the fact that
                 // the first N elements in the ClosureSubsts are
                 // inherited from the `closure_base_def_id`.
@@ -648,10 +651,10 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> {
                 )
             }
 
-            DefiningTy::Generator(def_id, substs, interior) => {
+            DefiningTy::Generator(def_id, substs, interior, movability) => {
                 assert_eq!(self.mir_def_id, def_id);
                 let output = substs.generator_return_ty(def_id, tcx);
-                let generator_ty = tcx.mk_generator(def_id, substs, interior);
+                let generator_ty = tcx.mk_generator(def_id, substs, interior, movability);
                 let inputs_and_output = self.infcx.tcx.intern_type_list(&[generator_ty, output]);
                 ty::Binder::dummy(inputs_and_output)
             }
diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs
index 9e96fdf8214..593c43e1ab4 100644
--- a/src/librustc_mir/build/expr/as_rvalue.rs
+++ b/src/librustc_mir/build/expr/as_rvalue.rs
@@ -185,12 +185,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
 
                 block.and(Rvalue::Aggregate(box AggregateKind::Tuple, fields))
             }
-            ExprKind::Closure { closure_id, substs, upvars, interior } => { // see (*) above
+            ExprKind::Closure { closure_id, substs, upvars, interior } => {
+                // see (*) above
                 let mut operands: Vec<_> =
                     upvars.into_iter()
                           .map(|upvar| unpack!(block = this.as_operand(block, scope, upvar)))
                           .collect();
-                let result = if let Some(interior) = interior {
+                let result = if let Some((interior, movability)) = interior {
                     // Add the state operand since it follows the upvars in the generator
                     // struct. See librustc_mir/transform/generator.rs for more details.
                     operands.push(Operand::Constant(box Constant {
@@ -203,7 +204,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                             }),
                         },
                     }));
-                    box AggregateKind::Generator(closure_id, substs, interior)
+                    box AggregateKind::Generator(closure_id, substs, interior, movability)
                 } else {
                     box AggregateKind::Closure(closure_id, substs)
                 };
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index d0c352319c8..966092ac5df 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -472,7 +472,9 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             let closure_ty = cx.tables().expr_ty(expr);
             let (def_id, substs, interior) = match closure_ty.sty {
                 ty::TyClosure(def_id, substs) => (def_id, substs, None),
-                ty::TyGenerator(def_id, substs, interior) => (def_id, substs, Some(interior)),
+                ty::TyGenerator(def_id, substs, interior, movability) =>{
+                    (def_id, substs, Some((interior, movability)))
+                }
                 _ => {
                     span_bug!(expr.span, "closure expr w/o closure type: {:?}", closure_ty);
                 }
diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs
index fe82b8158f7..0b6a1e3f52d 100644
--- a/src/librustc_mir/hair/mod.rs
+++ b/src/librustc_mir/hair/mod.rs
@@ -268,7 +268,7 @@ pub enum ExprKind<'tcx> {
         closure_id: DefId,
         substs: ClosureSubsts<'tcx>,
         upvars: Vec<ExprRef<'tcx>>,
-        interior: Option<GeneratorInterior<'tcx>>,
+        interior: Option<(GeneratorInterior<'tcx>, hir::GeneratorMovability)>,
     },
     Literal {
         literal: Literal<'tcx>,
diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs
index 9e43bed1b63..7b152bc1286 100644
--- a/src/librustc_mir/monomorphize/item.rs
+++ b/src/librustc_mir/monomorphize/item.rs
@@ -376,7 +376,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
                     self.push_type_name(sig.output(), output);
                 }
             },
-            ty::TyGenerator(def_id, ref closure_substs, _) |
+            ty::TyGenerator(def_id, ref closure_substs, _, _) |
             ty::TyClosure(def_id, ref closure_substs) => {
                 self.push_def_path(def_id, output);
                 let generics = self.tcx.generics_of(self.tcx.closure_base_def_id(def_id));
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 699a5b17435..a86e077927c 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -166,7 +166,7 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     debug!("build_drop_shim(def_id={:?}, ty={:?})", def_id, ty);
 
     // Check if this is a generator, if so, return the drop glue for it
-    if let Some(&ty::TyS { sty: ty::TyGenerator(gen_def_id, substs, _), .. }) = ty {
+    if let Some(&ty::TyS { sty: ty::TyGenerator(gen_def_id, substs, _, _), .. }) = ty {
         let mir = &**tcx.optimized_mir(gen_def_id).generator_drop.as_ref().unwrap();
         return mir.subst(tcx, substs.substs);
     }
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index 2bf5a49c97e..32d68962a0d 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -127,7 +127,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
                 &AggregateKind::Tuple |
                 &AggregateKind::Adt(..) => {}
                 &AggregateKind::Closure(def_id, _) |
-                &AggregateKind::Generator(def_id, _, _) => {
+                &AggregateKind::Generator(def_id, _, _, _) => {
                     let UnsafetyCheckResult {
                         violations, unsafe_blocks
                     } = self.tcx.unsafety_check_result(def_id);
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index 36735586e81..168f24f2cee 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -465,6 +465,7 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             source: MirSource,
                             upvars: Vec<Ty<'tcx>>,
                             interior: GeneratorInterior<'tcx>,
+                            movable: bool,
                             mir: &mut Mir<'tcx>)
     -> (HashMap<Local, (Ty<'tcx>, usize)>,
         GeneratorLayout<'tcx>,
@@ -474,7 +475,7 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let (live_locals, storage_liveness) = locals_live_across_suspend_points(tcx,
                                                                             mir,
                                                                             source,
-                                                                            interior.movable);
+                                                                            movable);
     // Erase regions from the types passed in from typeck so we can compare them with
     // MIR types
     let allowed_upvars = tcx.erase_regions(&upvars);
@@ -853,9 +854,11 @@ impl MirPass for StateTransform {
         let gen_ty = mir.local_decls.raw[1].ty;
 
         // Get the interior types and substs which typeck computed
-        let (upvars, interior) = match gen_ty.sty {
-            ty::TyGenerator(_, substs, interior) => {
-                (substs.upvar_tys(def_id, tcx).collect(), interior)
+        let (upvars, interior, movable) = match gen_ty.sty {
+            ty::TyGenerator(_, substs, interior, movability) => {
+                (substs.upvar_tys(def_id, tcx).collect(),
+                 interior,
+                 movability == hir::GeneratorMovability::Movable)
             }
             _ => bug!(),
         };
@@ -874,7 +877,13 @@ impl MirPass for StateTransform {
         // Extract locals which are live across suspension point into `layout`
         // `remap` gives a mapping from local indices onto generator struct indices
         // `storage_liveness` tells us which locals have live storage at suspension points
-        let (remap, layout, storage_liveness) = compute_layout(tcx, source, upvars, interior, mir);
+        let (remap, layout, storage_liveness) = compute_layout(
+            tcx,
+            source,
+            upvars,
+            interior,
+            movable,
+            mir);
 
         let state_field = mir.upvar_decls.len();
 
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index 4b7c581d3c8..1c04fe170a1 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -787,7 +787,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
             // This should only happen for the self argument on the resume function.
             // It effetively only contains upvars until the generator transformation runs.
             // See librustc_mir/transform/generator.rs for more details.
-            ty::TyGenerator(def_id, substs, _) => {
+            ty::TyGenerator(def_id, substs, _, _) => {
                 let tys : Vec<_> = substs.upvar_tys(def_id, self.tcx()).collect();
                 self.open_drop_for_tuple(&tys)
             }
diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs
index a891e372ad8..ddee5558c0f 100644
--- a/src/librustc_mir/util/pretty.rs
+++ b/src/librustc_mir/util/pretty.rs
@@ -418,11 +418,12 @@ impl<'cx, 'gcx, 'tcx> Visitor<'tcx> for ExtraComments<'cx, 'gcx, 'tcx> {
                     self.push(&format!("+ substs: {:#?}", substs));
                 }
 
-                AggregateKind::Generator(def_id, substs, interior) => {
+                AggregateKind::Generator(def_id, substs, interior, movability) => {
                     self.push(&format!("generator"));
                     self.push(&format!("+ def_id: {:?}", def_id));
                     self.push(&format!("+ substs: {:#?}", substs));
                     self.push(&format!("+ interior: {:?}", interior));
+                    self.push(&format!("+ movability: {:?}", movability));
                 }
 
                 _ => {}
diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs
index ba31ce2692f..8e4f82d2e1e 100644
--- a/src/librustc_traits/dropck_outlives.rs
+++ b/src/librustc_traits/dropck_outlives.rs
@@ -193,7 +193,7 @@ fn dtorck_constraint_for_ty<'a, 'gcx, 'tcx>(
             .map(|ty| dtorck_constraint_for_ty(tcx, span, for_ty, depth + 1, ty))
             .collect(),
 
-        ty::TyGenerator(def_id, substs, _interior) => {
+        ty::TyGenerator(def_id, substs, _interior, _movability) => {
             // rust-lang/rust#49918: types can be constructed, stored
             // in the interior, and sit idle when generator yields
             // (and is subsequently dropped).
diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs
index 4a0619b2336..004fb0f08f9 100644
--- a/src/librustc_trans/common.rs
+++ b/src/librustc_trans/common.rs
@@ -421,7 +421,7 @@ pub fn ty_fn_sig<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
                 sig.abi
             ))
         }
-        ty::TyGenerator(def_id, substs, _) => {
+        ty::TyGenerator(def_id, substs, _, _) => {
             let tcx = cx.tcx;
             let sig = substs.generator_poly_sig(def_id, cx.tcx);
 
diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs
index f16fef5ec1e..a025057faaf 100644
--- a/src/librustc_trans/debuginfo/metadata.rs
+++ b/src/librustc_trans/debuginfo/metadata.rs
@@ -591,7 +591,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
                                    unique_type_id,
                                    usage_site_span).finalize(cx)
         }
-        ty::TyGenerator(def_id, substs, _) => {
+        ty::TyGenerator(def_id, substs, _, _) => {
             let upvar_tys : Vec<_> = substs.field_tys(def_id, cx.tcx).map(|t| {
                 cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t)
             }).collect();
diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs
index a074f25dfc9..ab01984aa0f 100644
--- a/src/librustc_trans/mir/mod.rs
+++ b/src/librustc_trans/mir/mod.rs
@@ -577,7 +577,7 @@ fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
 
             let upvar_tys = match closure_layout.ty.sty {
                 ty::TyClosure(def_id, substs) |
-                ty::TyGenerator(def_id, substs, _) => substs.upvar_tys(def_id, tcx),
+                ty::TyGenerator(def_id, substs, _, _) => substs.upvar_tys(def_id, tcx),
                 _ => bug!("upvar_decls with non-closure arg0 type `{}`", closure_layout.ty)
             };
 
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index 3b9d561ffc5..cbe66746a29 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -116,7 +116,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         let substs = ty::ClosureSubsts { substs };
         let closure_type = self.tcx.mk_closure(expr_def_id, substs);
 
-        if let Some(GeneratorTypes { yield_ty, interior }) = generator_types {
+        if let Some(GeneratorTypes { yield_ty, interior, movability }) = generator_types {
             self.demand_eqtype(
                 expr.span,
                 yield_ty,
@@ -127,7 +127,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 liberated_sig.output(),
                 substs.generator_return_ty(expr_def_id, self.tcx),
             );
-            return self.tcx.mk_generator(expr_def_id, substs, interior);
+            return self.tcx.mk_generator(expr_def_id, substs, interior, movability);
         }
 
         debug!(
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index db859e42057..25c226e4591 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1009,7 +1009,10 @@ struct GeneratorTypes<'tcx> {
     yield_ty: ty::Ty<'tcx>,
 
     /// Types that are captured (see `GeneratorInterior` for more).
-    interior: ty::GeneratorInterior<'tcx>
+    interior: ty::GeneratorInterior<'tcx>,
+
+    /// Indicates if the generator is movable or static (immovable)
+    movability: hir::GeneratorMovability,
 }
 
 /// Helper used for fns and closures. Does the grungy work of checking a function
@@ -1085,12 +1088,13 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
     // resolve_generator_interiors relies on this property.
     let gen_ty = if can_be_generator.is_some() && body.is_generator {
         let witness = fcx.next_ty_var(TypeVariableOrigin::MiscVariable(span));
-        let interior = ty::GeneratorInterior {
-            witness,
-            movable: can_be_generator.unwrap() == hir::GeneratorMovability::Movable,
-        };
+        let interior = ty::GeneratorInterior { witness };
         fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior));
-        Some(GeneratorTypes { yield_ty: fcx.yield_ty.unwrap(), interior: interior })
+        Some(GeneratorTypes {
+            yield_ty: fcx.yield_ty.unwrap(),
+            interior: interior,
+            movability: can_be_generator.unwrap(),
+        })
     } else {
         None
     };
diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs
index 58dc5839578..5008b5d79bf 100644
--- a/src/librustc_typeck/check/upvar.rs
+++ b/src/librustc_typeck/check/upvar.rs
@@ -110,7 +110,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
         // Extract the type of the closure.
         let (closure_def_id, closure_substs) = match self.node_ty(closure_hir_id).sty {
-            ty::TyClosure(def_id, substs) | ty::TyGenerator(def_id, substs, _) => (def_id, substs),
+            ty::TyClosure(def_id, substs) |
+            ty::TyGenerator(def_id, substs, _, _) => (def_id, substs),
             ref t => {
                 span_bug!(
                     span,