From 0117033c721d35ade8d815e1fbf83f10d73f15e4 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 23 Jan 2020 19:13:36 +0100 Subject: [PATCH] Add a resume type param to the generator substs ...and unify it with `()` for now --- src/librustc/infer/opaque_types/mod.rs | 1 + src/librustc/traits/util.rs | 2 +- src/librustc/ty/structural_impls.rs | 4 +-- src/librustc/ty/sty.rs | 41 ++++++++++++++++++++------ src/librustc_typeck/check/closure.rs | 5 ++++ src/librustc_typeck/collect.rs | 2 +- 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 { - 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>; impl<'tcx> PolyGenSig<'tcx> { + pub fn resume_ty(&self) -> ty::Binder> { + self.map_bound_ref(|sig| sig.resume_ty) + } pub fn yield_ty(&self) -> ty::Binder> { 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 @@ -94,6 +94,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); if let Some(GeneratorTypes { yield_ty, interior, movability }) = generator_types { 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, 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() { - &["", "", ""][..] + &["", "", "", ""][..] } else { &["", ""][..] };