about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustc/ty/sty.rs24
-rw-r--r--src/librustc_mir/build/expr/as_rvalue.rs5
-rw-r--r--src/librustc_mir/transform/generator.rs13
3 files changed, 25 insertions, 17 deletions
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 9a90ccda914..1ac18f6117f 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -298,14 +298,10 @@ static_assert!(MEM_SIZE_OF_TY_KIND: ::std::mem::size_of::<TyKind<'_>>() == 24);
 ///
 /// ## Generators
 ///
-/// Perhaps surprisingly, `ClosureSubsts` are also used for
-/// generators. In that case, what is written above is only half-true
-/// -- the set of type parameters is similar, but the role of CK and
-/// CS are different. CK represents the "yield type" and CS
-/// represents the "return type" of the generator.
-///
-/// It'd be nice to split this struct into ClosureSubsts and
-/// GeneratorSubsts, I believe. -nmatsakis
+/// Generators are handled similarly in `GeneratorSubsts`.  The set of
+/// type parameters is similar, but the role of CK and CS are
+/// different. CK represents the "yield type" and CS represents the
+/// "return type" of the generator.
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
          Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct ClosureSubsts<'tcx> {
@@ -391,6 +387,7 @@ impl<'tcx> ClosureSubsts<'tcx> {
     }
 }
 
+/// Similar to `ClosureSubsts`; see the above documentation for more.
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug,
          RustcEncodable, RustcDecodable, HashStable)]
 pub struct GeneratorSubsts<'tcx> {
@@ -470,6 +467,11 @@ impl<'tcx> GeneratorSubsts<'tcx> {
 }
 
 impl<'a, 'gcx, 'tcx> GeneratorSubsts<'tcx> {
+    /// The type of the state "discriminant" used in the generator type.
+    pub fn discr_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
+        tcx.types.u32
+    }
+
     /// This returns the types of the MIR locals which had to be stored across suspension points.
     /// It is calculated in rustc_mir::transform::generator::StateTransform.
     /// All the types here must be in the tuple in GeneratorInterior.
@@ -484,15 +486,15 @@ impl<'a, 'gcx, 'tcx> GeneratorSubsts<'tcx> {
 
     /// This is the types of the fields of a generate which
     /// is available before the generator transformation.
-    /// It includes the upvars and the state discriminant which is u32.
+    /// It includes the upvars and the state discriminant.
     pub fn pre_transforms_tys(self, def_id: DefId, tcx: TyCtxt<'a, 'gcx, 'tcx>) ->
         impl Iterator<Item=Ty<'tcx>> + 'a
     {
-        self.upvar_tys(def_id, tcx).chain(iter::once(tcx.types.u32))
+        self.upvar_tys(def_id, tcx).chain(iter::once(self.discr_ty(tcx)))
     }
 
     /// This is the types of all the fields stored in a generator.
-    /// It includes the upvars, state types and the state discriminant which is u32.
+    /// It includes the upvars, state types and the state discriminant.
     pub fn field_tys(self, def_id: DefId, tcx: TyCtxt<'a, 'gcx, 'tcx>) ->
         impl Iterator<Item=Ty<'tcx>> + Captures<'gcx> + 'a
     {
diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs
index c58b570d8fc..0871217c524 100644
--- a/src/librustc_mir/build/expr/as_rvalue.rs
+++ b/src/librustc_mir/build/expr/as_rvalue.rs
@@ -255,15 +255,16 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                         let movability = movability.unwrap();
                         // Add the state operand since it follows the upvars in the generator
                         // struct. See librustc_mir/transform/generator.rs for more details.
+                        let discr_ty = substs.discr_ty(this.hir.tcx());
                         operands.push(Operand::Constant(box Constant {
                             span: expr_span,
-                            ty: this.hir.tcx().types.u32,
+                            ty: discr_ty,
                             user_ty: None,
                             literal: this.hir.tcx().mk_const(
                                 ty::Const::from_bits(
                                     this.hir.tcx(),
                                     0,
-                                    ty::ParamEnv::empty().and(this.hir.tcx().types.u32),
+                                    ty::ParamEnv::empty().and(discr_ty),
                                 ),
                             ),
                         }));
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index 2b909feb960..cf7397ca488 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -166,6 +166,9 @@ struct TransformVisitor<'a, 'tcx: 'a> {
     // The index of the generator state in the generator struct
     state_field: usize,
 
+    // The type of the generator state in the generator struct
+    discr_ty: Ty<'tcx>,
+
     // Mapping from Local to (type of local, generator struct index)
     // FIXME(eddyb) This should use `IndexVec<Local, Option<_>>`.
     remap: FxHashMap<Local, (Ty<'tcx>, usize)>,
@@ -200,15 +203,15 @@ impl<'a, 'tcx> TransformVisitor<'a, 'tcx> {
 
     // Create a statement which changes the generator state
     fn set_state(&self, state_disc: u32, source_info: SourceInfo) -> Statement<'tcx> {
-        let state = self.make_field(self.state_field, self.tcx.types.u32);
+        let state = self.make_field(self.state_field, self.discr_ty);
         let val = Operand::Constant(box Constant {
             span: source_info.span,
-            ty: self.tcx.types.u32,
+            ty: self.discr_ty,
             user_ty: None,
             literal: self.tcx.mk_const(ty::Const::from_bits(
                 self.tcx,
                 state_disc.into(),
-                ty::ParamEnv::empty().and(self.tcx.types.u32)
+                ty::ParamEnv::empty().and(self.discr_ty)
             )),
         });
         Statement {
@@ -889,10 +892,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, movable) = match gen_ty.sty {
+        let (upvars, interior, discr_ty, movable) = match gen_ty.sty {
             ty::Generator(_, substs, movability) => {
                 (substs.upvar_tys(def_id, tcx).collect(),
                  substs.witness(def_id, tcx),
+                 substs.discr_ty(tcx),
                  movability == hir::GeneratorMovability::Movable)
             }
             _ => bug!(),
@@ -937,6 +941,7 @@ impl MirPass for StateTransform {
             suspension_points: Vec::new(),
             new_ret_local,
             state_field,
+            discr_ty,
         };
         transform.visit_mir(mir);