about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustc/infer/opaque_types/mod.rs1
-rw-r--r--src/librustc/traits/util.rs2
-rw-r--r--src/librustc/ty/structural_impls.rs4
-rw-r--r--src/librustc/ty/sty.rs41
-rw-r--r--src/librustc_typeck/check/closure.rs5
-rw-r--r--src/librustc_typeck/collect.rs2
6 files changed, 42 insertions, 13 deletions
diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs
index fe3a5d149f6..d28507f6eb2 100644
--- a/src/librustc/infer/opaque_types/mod.rs
+++ b/src/librustc/infer/opaque_types/mod.rs
@@ -744,6 +744,7 @@ where
 
                 substs.as_generator().return_ty(def_id, self.tcx).visit_with(self);
                 substs.as_generator().yield_ty(def_id, self.tcx).visit_with(self);
+                substs.as_generator().resume_ty(def_id, self.tcx).visit_with(self);
             }
             _ => {
                 ty.super_visit_with(self);
diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs
index 947d66e38b4..d4c3518260c 100644
--- a/src/librustc/traits/util.rs
+++ b/src/librustc/traits/util.rs
@@ -645,7 +645,7 @@ pub fn generator_trait_ref_and_outputs(
 ) -> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> {
     let trait_ref = ty::TraitRef {
         def_id: fn_trait_def_id,
-        substs: tcx.mk_substs_trait(self_ty, &[tcx.mk_unit().into()]),
+        substs: tcx.mk_substs_trait(self_ty, &[sig.skip_binder().resume_ty.into()]),
     };
     ty::Binder::bind((trait_ref, sig.skip_binder().yield_ty, sig.skip_binder().return_ty))
 }
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index c1ae4d9fe17..9d00d272263 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -598,8 +598,8 @@ impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> {
 impl<'a, 'tcx> Lift<'tcx> for ty::GenSig<'a> {
     type Lifted = ty::GenSig<'tcx>;
     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&(self.yield_ty, self.return_ty))
-            .map(|(yield_ty, return_ty)| ty::GenSig { yield_ty, return_ty })
+        tcx.lift(&(self.resume_ty, self.yield_ty, self.return_ty))
+            .map(|(resume_ty, yield_ty, return_ty)| ty::GenSig { resume_ty, yield_ty, return_ty })
     }
 }
 
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index dffe86d9462..0d30395d250 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -346,9 +346,17 @@ static_assert_size!(TyKind<'_>, 24);
 /// ## Generators
 ///
 /// 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.
+/// type parameters is similar, but `CK` and `CS` are replaced by the
+/// following type parameters:
+///
+/// * `GS`: The generator's "resume type", which is the type of the
+///   argument passed to `resume`, and the type of `yield` expressions
+///   inside the generator.
+/// * `GY`: The "yield type", which is the type of values passed to
+///   `yield` inside the generator.
+/// * `GR`: The "return type", which is the type of value returned upon
+///   completion of the generator.
+/// * `GW`: The "generator witness".
 #[derive(Copy, Clone, Debug, TypeFoldable)]
 pub struct ClosureSubsts<'tcx> {
     /// Lifetime and type parameters from the enclosing function,
@@ -442,6 +450,7 @@ pub struct GeneratorSubsts<'tcx> {
 }
 
 struct SplitGeneratorSubsts<'tcx> {
+    resume_ty: Ty<'tcx>,
     yield_ty: Ty<'tcx>,
     return_ty: Ty<'tcx>,
     witness: Ty<'tcx>,
@@ -453,10 +462,11 @@ impl<'tcx> GeneratorSubsts<'tcx> {
         let generics = tcx.generics_of(def_id);
         let parent_len = generics.parent_count;
         SplitGeneratorSubsts {
-            yield_ty: self.substs.type_at(parent_len),
-            return_ty: self.substs.type_at(parent_len + 1),
-            witness: self.substs.type_at(parent_len + 2),
-            upvar_kinds: &self.substs[parent_len + 3..],
+            resume_ty: self.substs.type_at(parent_len),
+            yield_ty: self.substs.type_at(parent_len + 1),
+            return_ty: self.substs.type_at(parent_len + 2),
+            witness: self.substs.type_at(parent_len + 3),
+            upvar_kinds: &self.substs[parent_len + 4..],
         }
     }
 
@@ -485,6 +495,11 @@ impl<'tcx> GeneratorSubsts<'tcx> {
         })
     }
 
+    /// Returns the type representing the resume type of the generator.
+    pub fn resume_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
+        self.split(def_id, tcx).resume_ty
+    }
+
     /// Returns the type representing the yield type of the generator.
     pub fn yield_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
         self.split(def_id, tcx).yield_ty
@@ -505,10 +520,14 @@ impl<'tcx> GeneratorSubsts<'tcx> {
         ty::Binder::dummy(self.sig(def_id, tcx))
     }
 
-    /// Returns the "generator signature", which consists of its yield
+    /// Returns the "generator signature", which consists of its resume, yield
     /// and return types.
     pub fn sig(self, def_id: DefId, tcx: TyCtxt<'_>) -> GenSig<'tcx> {
-        ty::GenSig { yield_ty: self.yield_ty(def_id, tcx), return_ty: self.return_ty(def_id, tcx) }
+        ty::GenSig {
+            resume_ty: self.resume_ty(def_id, tcx),
+            yield_ty: self.yield_ty(def_id, tcx),
+            return_ty: self.return_ty(def_id, tcx),
+        }
     }
 }
 
@@ -1072,6 +1091,7 @@ impl<'tcx> ProjectionTy<'tcx> {
 
 #[derive(Clone, Debug, TypeFoldable)]
 pub struct GenSig<'tcx> {
+    pub resume_ty: Ty<'tcx>,
     pub yield_ty: Ty<'tcx>,
     pub return_ty: Ty<'tcx>,
 }
@@ -1079,6 +1099,9 @@ pub struct GenSig<'tcx> {
 pub type PolyGenSig<'tcx> = Binder<GenSig<'tcx>>;
 
 impl<'tcx> PolyGenSig<'tcx> {
+    pub fn resume_ty(&self) -> ty::Binder<Ty<'tcx>> {
+        self.map_bound_ref(|sig| sig.resume_ty)
+    }
     pub fn yield_ty(&self) -> ty::Binder<Ty<'tcx>> {
         self.map_bound_ref(|sig| sig.yield_ty)
     }
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index 084e6c8d083..97067e0b055 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -96,6 +96,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let generator_substs = substs.as_generator();
             self.demand_eqtype(
                 expr.span,
+                self.tcx.mk_unit(),  // WIP
+                generator_substs.resume_ty(expr_def_id, self.tcx),
+            );
+            self.demand_eqtype(
+                expr.span,
                 yield_ty,
                 generator_substs.yield_ty(expr_def_id, self.tcx),
             );
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 4d812d2621c..dc089c90456 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -1189,7 +1189,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics {
     // and we don't do that for closures.
     if let Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(.., gen), .. }) = node {
         let dummy_args = if gen.is_some() {
-            &["<yield_ty>", "<return_ty>", "<witness>"][..]
+            &["<resume_ty>", "<yield_ty>", "<return_ty>", "<witness>"][..]
         } else {
             &["<closure_kind>", "<closure_signature>"][..]
         };