From 710b4ad2a5cc8e70b42d6d85ebe4eacc5b65548b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 2 May 2018 13:14:30 +0200 Subject: [PATCH] Store the GeneratorInterior in the new GeneratorSubsts --- src/librustc/ich/impls_mir.rs | 3 +- src/librustc/ich/impls_ty.rs | 12 +- src/librustc/mir/mod.rs | 16 +- src/librustc/mir/tcx.rs | 6 +- src/librustc/mir/visit.rs | 18 +-- src/librustc/traits/mod.rs | 6 +- src/librustc/traits/project.rs | 2 +- src/librustc/traits/select.rs | 24 +-- src/librustc/traits/structural_impls.rs | 10 +- src/librustc/ty/context.rs | 18 +-- src/librustc/ty/fast_reject.rs | 2 +- src/librustc/ty/flags.rs | 3 +- src/librustc/ty/instance.rs | 9 +- src/librustc/ty/item_path.rs | 2 +- src/librustc/ty/layout.rs | 4 +- src/librustc/ty/mod.rs | 2 +- src/librustc/ty/outlives.rs | 2 +- src/librustc/ty/relate.rs | 23 ++- src/librustc/ty/structural_impls.rs | 21 ++- src/librustc/ty/sty.rs | 148 +++++++++++++----- src/librustc/ty/util.rs | 2 +- src/librustc/ty/walk.rs | 3 +- src/librustc/util/ppaux.rs | 13 +- .../borrow_check/error_reporting.rs | 2 +- src/librustc_mir/borrow_check/mod.rs | 13 +- .../borrow_check/nll/constraint_generation.rs | 9 +- .../nll/region_infer/annotation.rs | 7 +- src/librustc_mir/borrow_check/nll/renumber.rs | 16 +- .../borrow_check/nll/type_check/mod.rs | 6 +- .../borrow_check/nll/universal_regions.rs | 30 ++-- src/librustc_mir/build/expr/as_rvalue.rs | 40 ++--- src/librustc_mir/build/mod.rs | 2 +- src/librustc_mir/hair/cx/expr.rs | 10 +- src/librustc_mir/hair/mod.rs | 6 +- src/librustc_mir/monomorphize/item.rs | 8 +- src/librustc_mir/monomorphize/mod.rs | 3 +- src/librustc_mir/shim.rs | 2 +- src/librustc_mir/transform/check_unsafety.rs | 2 +- src/librustc_mir/transform/erase_regions.rs | 6 - src/librustc_mir/transform/generator.rs | 10 +- src/librustc_mir/util/elaborate_drops.rs | 7 +- src/librustc_mir/util/pretty.rs | 3 +- src/librustc_traits/dropck_outlives.rs | 2 +- src/librustc_trans/common.rs | 4 +- src/librustc_trans/debuginfo/metadata.rs | 2 +- src/librustc_trans/mir/mod.rs | 9 +- src/librustc_typeck/check/closure.rs | 18 ++- .../check/generator_interior.rs | 6 +- src/librustc_typeck/check/mod.rs | 9 +- src/librustc_typeck/check/upvar.rs | 34 ++-- src/librustc_typeck/collect.rs | 50 +++--- 51 files changed, 357 insertions(+), 308 deletions(-) diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index 29a0632511c32..c71b10ce142c5 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -483,10 +483,9 @@ for mir::AggregateKind<'gcx> { def_id.hash_stable(hcx, hasher); substs.hash_stable(hcx, hasher); } - mir::AggregateKind::Generator(def_id, ref substs, ref interior, movability) => { + mir::AggregateKind::Generator(def_id, ref substs, 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 96ef8591645aa..42fde0a19030f 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -517,8 +517,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 }); +impl_stable_hash_for!(struct ty::GeneratorSubsts<'tcx> { substs }); impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> { parent, @@ -908,10 +907,9 @@ for ty::TypeVariants<'gcx> def_id.hash_stable(hcx, hasher); closure_substs.hash_stable(hcx, hasher); } - TyGenerator(def_id, closure_substs, interior, movability) => { + TyGenerator(def_id, generator_substs, movability) => { def_id.hash_stable(hcx, hasher); - closure_substs.hash_stable(hcx, hasher); - interior.hash_stable(hcx, hasher); + generator_substs.hash_stable(hcx, hasher); movability.hash_stable(hcx, hasher); } TyGeneratorWitness(types) => { @@ -1316,11 +1314,11 @@ for traits::VtableGeneratorData<'gcx, N> where N: HashStable, hasher: &mut StableHasher) { let traits::VtableGeneratorData { - closure_def_id, + generator_def_id, substs, ref nested, } = *self; - closure_def_id.hash_stable(hcx, hasher); + generator_def_id.hash_stable(hcx, hasher); substs.hash_stable(hcx, hasher); nested.hash_stable(hcx, hasher); } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 907ffc6760605..cc9c5cadc9389 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -27,7 +27,7 @@ use hir::def_id::DefId; use mir::visit::MirVisitable; use mir::interpret::{Value, PrimVal, EvalErrorKind}; use ty::subst::{Subst, Substs}; -use ty::{self, AdtDef, CanonicalTy, ClosureSubsts, Region, Ty, TyCtxt, GeneratorInterior}; +use ty::{self, AdtDef, CanonicalTy, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use ty::TypeAndMut; use util::ppaux; @@ -1641,7 +1641,7 @@ pub enum AggregateKind<'tcx> { Adt(&'tcx AdtDef, usize, &'tcx Substs<'tcx>, Option), Closure(DefId, ClosureSubsts<'tcx>), - Generator(DefId, ClosureSubsts<'tcx>, GeneratorInterior<'tcx>, hir::GeneratorMovability), + Generator(DefId, GeneratorSubsts<'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,11 +2375,8 @@ 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, movablity) => - AggregateKind::Generator(id, - substs.fold_with(folder), - interior.fold_with(folder), - movablity), + AggregateKind::Generator(id, substs, movablity) => + AggregateKind::Generator(id, substs.fold_with(folder), movablity), }; Aggregate(kind, fields.fold_with(folder)) } @@ -2406,8 +2403,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) || - interior.visit_with(visitor), + AggregateKind::Generator(_, substs, _) => substs.visit_with(visitor), }) || fields.visit_with(visitor) } } diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index 33af199d75888..6a9ff39c5f56b 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -184,10 +184,10 @@ impl<'tcx> Rvalue<'tcx> { tcx.type_of(def.did).subst(tcx, substs) } AggregateKind::Closure(did, substs) => { - tcx.mk_closure_from_closure_substs(did, substs) + tcx.mk_closure(did, substs) } - AggregateKind::Generator(did, substs, interior, movability) => { - tcx.mk_generator(did, substs, interior, movability) + AggregateKind::Generator(did, substs, movability) => { + tcx.mk_generator(did, substs, movability) } } } diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 6aed5076c1f16..b647ba553dd6c 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -10,7 +10,7 @@ use hir::def_id::DefId; use ty::subst::Substs; -use ty::{CanonicalTy, ClosureSubsts, Region, Ty, GeneratorInterior}; +use ty::{CanonicalTy, ClosureSubsts, GeneratorSubsts, Region, Ty}; use mir::*; use syntax_pos::Span; @@ -243,10 +243,10 @@ macro_rules! make_mir_visitor { self.super_closure_substs(substs); } - fn visit_generator_interior(&mut self, - interior: & $($mutability)* GeneratorInterior<'tcx>, + fn visit_generator_substs(&mut self, + substs: & $($mutability)* GeneratorSubsts<'tcx>, _: Location) { - self.super_generator_interior(interior); + self.super_generator_substs(substs); } fn visit_local_decl(&mut self, @@ -595,12 +595,10 @@ 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)* generator_substs, _movability) => { self.visit_def_id(def_id, location); - self.visit_closure_substs(closure_substs, location); - self.visit_generator_interior(interior, location); + self.visit_generator_substs(generator_substs, location); } } @@ -787,8 +785,8 @@ macro_rules! make_mir_visitor { fn super_substs(&mut self, _substs: & $($mutability)* &'tcx Substs<'tcx>) { } - fn super_generator_interior(&mut self, - _interior: & $($mutability)* GeneratorInterior<'tcx>) { + fn super_generator_substs(&mut self, + _substs: & $($mutability)* GeneratorSubsts<'tcx>) { } fn super_closure_substs(&mut self, diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index dd5208e908e19..26adbd8267291 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -480,8 +480,8 @@ pub struct VtableImplData<'tcx, N> { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable)] pub struct VtableGeneratorData<'tcx, N> { - pub closure_def_id: DefId, - pub substs: ty::ClosureSubsts<'tcx>, + pub generator_def_id: DefId, + pub substs: ty::GeneratorSubsts<'tcx>, /// Nested obligations. This can be non-empty if the generator /// signature contains associated types. pub nested: Vec @@ -989,7 +989,7 @@ impl<'tcx, N> Vtable<'tcx, N> { nested: p.nested.into_iter().map(f).collect(), }), VtableGenerator(c) => VtableGenerator(VtableGeneratorData { - closure_def_id: c.closure_def_id, + generator_def_id: c.generator_def_id, substs: c.substs, nested: c.nested.into_iter().map(f).collect(), }), diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 45fa588bbf533..bfa32f8e7faf3 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -1288,7 +1288,7 @@ fn confirm_generator_candidate<'cx, 'gcx, 'tcx>( vtable: VtableGeneratorData<'tcx, PredicateObligation<'tcx>>) -> Progress<'tcx> { - let gen_sig = vtable.substs.generator_poly_sig(vtable.closure_def_id, selcx.tcx()); + let gen_sig = vtable.substs.poly_sig(vtable.generator_def_id, selcx.tcx()); let Normalized { value: gen_sig, obligations diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 82643c315b99d..e73e11075d4d4 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2280,8 +2280,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { substs.upvar_tys(def_id, self.tcx()).collect() } - ty::TyGenerator(def_id, ref substs, interior, _) => { - substs.upvar_tys(def_id, self.tcx()).chain(iter::once(interior.witness)).collect() + ty::TyGenerator(def_id, ref substs, _) => { + let witness = substs.witness(def_id, self.tcx()); + substs.upvar_tys(def_id, self.tcx()).chain(iter::once(witness)).collect() } ty::TyGeneratorWitness(types) => { @@ -2755,18 +2756,18 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // touch bound regions, they just capture the in-scope // 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), + let (generator_def_id, substs) = match self_ty.sty { + ty::TyGenerator(id, substs, _) => (id, substs), _ => bug!("closure candidate for non-closure {:?}", obligation) }; debug!("confirm_generator_candidate({:?},{:?},{:?})", obligation, - closure_def_id, + generator_def_id, substs); let trait_ref = - self.generator_trait_ref_unnormalized(obligation, closure_def_id, substs); + self.generator_trait_ref_unnormalized(obligation, generator_def_id, substs); let Normalized { value: trait_ref, mut obligations @@ -2776,8 +2777,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation.recursion_depth+1, &trait_ref); - debug!("confirm_generator_candidate(closure_def_id={:?}, trait_ref={:?}, obligations={:?})", - closure_def_id, + debug!("confirm_generator_candidate(generator_def_id={:?}, \ + trait_ref={:?}, obligations={:?})", + generator_def_id, trait_ref, obligations); @@ -2788,7 +2790,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { trait_ref)?); Ok(VtableGeneratorData { - closure_def_id: closure_def_id, + generator_def_id: generator_def_id, substs: substs.clone(), nested: obligations }) @@ -3294,10 +3296,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn generator_trait_ref_unnormalized(&mut self, obligation: &TraitObligation<'tcx>, closure_def_id: DefId, - substs: ty::ClosureSubsts<'tcx>) + substs: ty::GeneratorSubsts<'tcx>) -> ty::PolyTraitRef<'tcx> { - let gen_sig = substs.generator_poly_sig(closure_def_id, self.tcx()); + let gen_sig = substs.poly_sig(closure_def_id, self.tcx()); // (1) Feels icky to skip the binder here, but OTOH we know // that the self-type is an generator type and hence is diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index d7e42655bbb5b..822ea17009b6b 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -83,8 +83,8 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableImplData<'tcx, N> { impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableGeneratorData<'tcx, N> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "VtableGenerator(closure_def_id={:?}, substs={:?}, nested={:?})", - self.closure_def_id, + write!(f, "VtableGenerator(generator_def_id={:?}, substs={:?}, nested={:?})", + self.generator_def_id, self.substs, self.nested) } @@ -294,13 +294,13 @@ impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> { } traits::VtableAutoImpl(t) => Some(traits::VtableAutoImpl(t)), traits::VtableGenerator(traits::VtableGeneratorData { - closure_def_id, + generator_def_id, substs, nested }) => { tcx.lift(&substs).map(|substs| { traits::VtableGenerator(traits::VtableGeneratorData { - closure_def_id: closure_def_id, + generator_def_id: generator_def_id, substs: substs, nested: nested }) @@ -373,7 +373,7 @@ BraceStructTypeFoldableImpl! { BraceStructTypeFoldableImpl! { impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableGeneratorData<'tcx, N> { - closure_def_id, substs, nested + generator_def_id, substs, nested } where N: TypeFoldable<'tcx> } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 6ed243361c093..139b23591191c 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -41,7 +41,7 @@ use traits; use traits::{Clause, Clauses, Goal, Goals}; use ty::{self, Ty, TypeAndMut}; use ty::{TyS, TypeVariants, Slice}; -use ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorInterior, Region, Const}; +use ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorSubsts, Region, Const}; use ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate, Predicate}; use ty::RegionKind; use ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid}; @@ -2436,27 +2436,17 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { })) } - pub fn mk_closure(self, - closure_id: DefId, - substs: ClosureSubsts<'tcx>) - -> Ty<'tcx> { - self.mk_closure_from_closure_substs(closure_id, substs) - } - - pub fn mk_closure_from_closure_substs(self, - closure_id: DefId, - closure_substs: ClosureSubsts<'tcx>) + pub fn mk_closure(self, closure_id: DefId, closure_substs: ClosureSubsts<'tcx>) -> Ty<'tcx> { self.mk_ty(TyClosure(closure_id, closure_substs)) } pub fn mk_generator(self, id: DefId, - closure_substs: ClosureSubsts<'tcx>, - interior: GeneratorInterior<'tcx>, + generator_substs: GeneratorSubsts<'tcx>, movability: hir::GeneratorMovability) -> Ty<'tcx> { - self.mk_ty(TyGenerator(id, closure_substs, interior, movability)) + self.mk_ty(TyGenerator(id, generator_substs, movability)) } pub fn mk_generator_witness(self, types: ty::Binder<&'tcx Slice>>) -> Ty<'tcx> { diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs index 2b6901f74def9..31b3ca44700e9 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 acc17a08a80d7..bb707c556c0a8 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -87,11 +87,10 @@ impl FlagComputation { } } - &ty::TyGenerator(_, ref substs, ref interior, _) => { + &ty::TyGenerator(_, ref substs, _) => { self.add_flags(TypeFlags::HAS_TY_CLOSURE); self.add_flags(TypeFlags::HAS_LOCAL_NAMES); self.add_substs(&substs.substs); - self.add_ty(interior.witness); } &ty::TyGeneratorWitness(ref ts) => { diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index ecd415c4bc420..e7b71ca2b228e 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -270,10 +270,10 @@ fn resolve_associated_item<'a, 'tcx>( let substs = tcx.erase_regions(&substs); Some(ty::Instance::new(def_id, substs)) } - traits::VtableGenerator(closure_data) => { + traits::VtableGenerator(generator_data) => { Some(Instance { - def: ty::InstanceDef::Item(closure_data.closure_def_id), - substs: closure_data.substs.substs + def: ty::InstanceDef::Item(generator_data.generator_def_id), + substs: generator_data.substs.substs }) } traits::VtableClosure(closure_data) => { @@ -356,8 +356,7 @@ fn fn_once_adapter_instance<'a, 'tcx>( .unwrap().def_id; let def = ty::InstanceDef::ClosureOnceShim { call_once }; - let self_ty = tcx.mk_closure_from_closure_substs( - closure_did, substs); + let self_ty = tcx.mk_closure(closure_did, substs); let sig = substs.closure_sig(closure_did, tcx); let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index b58c4138597d2..752b7f69a6a7f 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 { 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 7b91040b8e7de..02c4b73efa146 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::, _>>()?, &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/mod.rs b/src/librustc/ty/mod.rs index c4fe112a9e913..3bca65ec8185b 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -63,7 +63,7 @@ use hir; pub use self::sty::{Binder, CanonicalVar, DebruijnIndex}; pub use self::sty::{FnSig, GenSig, PolyFnSig, PolyGenSig}; pub use self::sty::{InferTy, ParamTy, ProjectionTy, ExistentialPredicate}; -pub use self::sty::{ClosureSubsts, GeneratorInterior, TypeAndMut}; +pub use self::sty::{ClosureSubsts, GeneratorSubsts, UpvarSubsts, TypeAndMut}; pub use self::sty::{TraitRef, TypeVariants, PolyTraitRef}; pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef}; pub use self::sty::{ExistentialProjection, PolyExistentialProjection, Const}; diff --git a/src/librustc/ty/outlives.rs b/src/librustc/ty/outlives.rs index 4eb736789f3cd..ff99a4b7ff638 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 ed0835418a484..8c3779b0c1e11 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -415,16 +415,15 @@ 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, movability), - &ty::TyGenerator(b_id, b_substs, b_interior, _)) + (&ty::TyGenerator(a_id, a_substs, movability), + &ty::TyGenerator(b_id, b_substs, _)) if a_id == b_id => { // All TyGenerator types with the same id represent // the (anonymous) type of the same generator expression. So // 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, movability)) + Ok(tcx.mk_generator(a_id, substs, movability)) } (&ty::TyGeneratorWitness(a_types), &ty::TyGeneratorWitness(b_types)) => @@ -446,7 +445,7 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R, // the (anonymous) type of the same closure expression. So // all of their regions should be equated. let substs = relation.relate(&a_substs, &b_substs)?; - Ok(tcx.mk_closure_from_closure_substs(a_id, substs)) + Ok(tcx.mk_closure(a_id, substs)) } (&ty::TyRawPtr(ref a_mt), &ty::TyRawPtr(ref b_mt)) => @@ -607,19 +606,19 @@ impl<'tcx> Relate<'tcx> for ty::ClosureSubsts<'tcx> { where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a { let substs = relate_substs(relation, None, a.substs, b.substs)?; - Ok(ty::ClosureSubsts { substs: substs }) + Ok(ty::ClosureSubsts { substs }) } } -impl<'tcx> Relate<'tcx> for ty::GeneratorInterior<'tcx> { +impl<'tcx> Relate<'tcx> for ty::GeneratorSubsts<'tcx> { fn relate<'a, 'gcx, R>(relation: &mut R, - a: &ty::GeneratorInterior<'tcx>, - b: &ty::GeneratorInterior<'tcx>) - -> RelateResult<'tcx, ty::GeneratorInterior<'tcx>> + a: &ty::GeneratorSubsts<'tcx>, + b: &ty::GeneratorSubsts<'tcx>) + -> RelateResult<'tcx, ty::GeneratorSubsts<'tcx>> where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a { - let witness = relation.relate(&a.witness, &b.witness)?; - Ok(ty::GeneratorInterior { witness }) + let substs = relate_substs(relation, None, a.substs, b.substs)?; + Ok(ty::GeneratorSubsts { substs }) } } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 6df3b5dc2bd1f..933756dcd3d91 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -304,16 +304,16 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ClosureSubsts<'a> { type Lifted = ty::ClosureSubsts<'tcx>; fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option { tcx.lift(&self.substs).map(|substs| { - ty::ClosureSubsts { substs: substs } + ty::ClosureSubsts { substs } }) } } -impl<'a, 'tcx> Lift<'tcx> for ty::GeneratorInterior<'a> { - type Lifted = ty::GeneratorInterior<'tcx>; +impl<'a, 'tcx> Lift<'tcx> for ty::GeneratorSubsts<'a> { + type Lifted = ty::GeneratorSubsts<'tcx>; fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option { - tcx.lift(&self.witness).map(|witness| { - ty::GeneratorInterior { witness } + tcx.lift(&self.substs).map(|substs| { + ty::GeneratorSubsts { substs } }) } } @@ -867,11 +867,10 @@ 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, movability) => { + ty::TyGenerator(did, substs, movability) => { ty::TyGenerator( did, substs.fold_with(folder), - interior.fold_with(folder), movability) } ty::TyGeneratorWitness(types) => ty::TyGeneratorWitness(types.fold_with(folder)), @@ -906,8 +905,8 @@ 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, _) => { - substs.visit_with(visitor) || interior.visit_with(visitor) + ty::TyGenerator(_did, ref substs, _) => { + substs.visit_with(visitor) } ty::TyGeneratorWitness(ref types) => types.visit_with(visitor), ty::TyClosure(_did, ref substs) => substs.visit_with(visitor), @@ -984,8 +983,8 @@ BraceStructTypeFoldableImpl! { } BraceStructTypeFoldableImpl! { - impl<'tcx> TypeFoldable<'tcx> for ty::GeneratorInterior<'tcx> { - witness, + impl<'tcx> TypeFoldable<'tcx> for ty::GeneratorSubsts<'tcx> { + substs, } } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index b2c715bf7b976..c7e67c974dd42 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>, hir::GeneratorMovability), + TyGenerator(DefId, GeneratorSubsts<'tcx>, hir::GeneratorMovability), /// A type representin the types stored inside a generator. /// This should only appear in GeneratorInteriors. @@ -328,37 +328,6 @@ impl<'tcx> ClosureSubsts<'tcx> { self.split(def_id, tcx).closure_sig_ty } - /// Returns the type representing the yield type of the generator. - pub fn generator_yield_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> { - self.closure_kind_ty(def_id, tcx) - } - - /// Returns the type representing the return type of the generator. - pub fn generator_return_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> { - self.closure_sig_ty(def_id, tcx) - } - - /// Return the "generator signature", which consists of its yield - /// and return types. - /// - /// NB. Some bits of the code prefers to see this wrapped in a - /// binder, but it never contains bound regions. Probably this - /// function should be removed. - pub fn generator_poly_sig(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> PolyGenSig<'tcx> { - ty::Binder::dummy(self.generator_sig(def_id, tcx)) - } - - /// Return the "generator signature", which consists of its yield - /// and return types. - pub fn generator_sig(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> GenSig<'tcx> { - ty::GenSig { - yield_ty: self.generator_yield_ty(def_id, tcx), - return_ty: self.generator_return_ty(def_id, tcx), - } - } -} - -impl<'tcx> ClosureSubsts<'tcx> { /// Returns the closure kind for this closure; only usable outside /// of an inference context, because in that context we know that /// there are no type variables. @@ -381,7 +350,84 @@ impl<'tcx> ClosureSubsts<'tcx> { } } -impl<'a, 'gcx, 'tcx> ClosureSubsts<'tcx> { +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] +pub struct GeneratorSubsts<'tcx> { + pub substs: &'tcx Substs<'tcx>, +} + +struct SplitGeneratorSubsts<'tcx> { + yield_ty: Ty<'tcx>, + return_ty: Ty<'tcx>, + witness: Ty<'tcx>, + upvar_kinds: &'tcx [Kind<'tcx>], +} + +impl<'tcx> GeneratorSubsts<'tcx> { + fn split(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> SplitGeneratorSubsts<'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..], + } + } + + /// This describes the types that can be contained in a generator. + /// It will be a type variable initially and unified in the last stages of typeck of a body. + /// It contains a tuple of all the types that could end up on a generator frame. + /// The state transformation MIR pass may only produce layouts which mention types + /// in this tuple. Upvars are not counted here. + pub fn witness(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> { + self.split(def_id, tcx).witness + } + + #[inline] + pub fn upvar_tys(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> + impl Iterator> + 'tcx + { + let SplitGeneratorSubsts { upvar_kinds, .. } = self.split(def_id, tcx); + upvar_kinds.iter().map(|t| { + if let UnpackedKind::Type(ty) = t.unpack() { + ty + } else { + bug!("upvar should be type") + } + }) + } + + /// 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 + } + + /// Returns the type representing the return type of the generator. + pub fn return_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> { + self.split(def_id, tcx).return_ty + } + + /// Return the "generator signature", which consists of its yield + /// and return types. + /// + /// NB. Some bits of the code prefers to see this wrapped in a + /// binder, but it never contains bound regions. Probably this + /// function should be removed. + pub fn poly_sig(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> PolyGenSig<'tcx> { + ty::Binder::dummy(self.sig(def_id, tcx)) + } + + /// Return the "generator signature", which consists of its 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), + } + } +} + +impl<'a, 'gcx, 'tcx> GeneratorSubsts<'tcx> { /// 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. @@ -412,14 +458,29 @@ impl<'a, 'gcx, 'tcx> ClosureSubsts<'tcx> { } } -/// This describes the types that can be contained in a generator. -/// It will be a type variable initially and unified in the last stages of typeck of a body. -/// It contains a tuple of all the types that could end up on a generator frame. -/// The state transformation MIR pass may only produce layouts which mention types in this tuple. -/// Upvars are not counted here. -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] -pub struct GeneratorInterior<'tcx> { - pub witness: Ty<'tcx>, +#[derive(Debug, Copy, Clone)] +pub enum UpvarSubsts<'tcx> { + Closure(ClosureSubsts<'tcx>), + Generator(GeneratorSubsts<'tcx>), +} + +impl<'tcx> UpvarSubsts<'tcx> { + #[inline] + pub fn upvar_tys(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> + impl Iterator> + 'tcx + { + let upvar_kinds = match self { + UpvarSubsts::Closure(substs) => substs.split(def_id, tcx).upvar_kinds, + UpvarSubsts::Generator(substs) => substs.split(def_id, tcx).upvar_kinds, + }; + upvar_kinds.iter().map(|t| { + if let UnpackedKind::Type(ty) = t.unpack() { + ty + } else { + bug!("upvar should be type") + } + }) + } } #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] @@ -1604,8 +1665,9 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { TyAdt(_, substs) | TyAnon(_, substs) => { substs.regions().collect() } - TyClosure(_, ref substs) | TyGenerator(_, ref substs, _, _) => { - substs.substs.regions().collect() + TyClosure(_, ClosureSubsts { ref substs }) | + TyGenerator(_, GeneratorSubsts { ref substs }, _) => { + substs.regions().collect() } TyProjection(ref data) => { data.substs.regions().collect() diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 12421715ed56e..4aa70e1f7e006 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 d3fa376d6a889..4567baf5ef4d3 100644 --- a/src/librustc/ty/walk.rs +++ b/src/librustc/ty/walk.rs @@ -118,8 +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, _) => { - stack.push(interior.witness); + ty::TyGenerator(_, ref substs, _) => { stack.extend(substs.substs.types().rev()); } ty::TyGeneratorWitness(ts) => { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 770357e549d7d..15e91404f6dc8 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -995,14 +995,6 @@ define_print! { } } -define_print! { - ('tcx) ty::GeneratorInterior<'tcx>, (self, f, cx) { - display { - self.witness.print(f, cx) - } - } -} - define_print! { ('tcx) ty::TypeVariants<'tcx>, (self, f, cx) { display { @@ -1110,8 +1102,9 @@ define_print! { }) } TyStr => write!(f, "str"), - TyGenerator(did, substs, interior, movability) => ty::tls::with(|tcx| { + TyGenerator(did, substs, movability) => ty::tls::with(|tcx| { let upvar_tys = substs.upvar_tys(did, tcx); + let witness = substs.witness(did, tcx); if movability == hir::GeneratorMovability::Movable { write!(f, "[generator")?; } else { @@ -1145,7 +1138,7 @@ define_print! { } } - print!(f, cx, write(" "), print(interior), write("]")) + print!(f, cx, write(" "), print(witness), write("]")) }), TyGeneratorWitness(types) => { ty::tls::with(|tcx| cx.in_binder(f, tcx, &types, tcx.lift(&types))) diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index f68c164751d6f..db2e078586eda 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/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 3e3f510e308c3..953238a721890 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -835,10 +835,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { tys.iter().cloned().enumerate() .for_each(|field| drop_field(self, field)); } - // Closures and generators also have disjoint fields, but they are only - // directly accessed in the body of the closure/generator. + // Closures also have disjoint fields, but they are only + // directly accessed in the body of the closure. ty::TyClosure(def, substs) - | ty::TyGenerator(def, substs, ..) + if *drop_place == Place::Local(Local::new(1)) && !self.mir.upvar_decls.is_empty() + => { + substs.upvar_tys(def, self.tcx).enumerate() + .for_each(|field| drop_field(self, field)); + } + // Generators also have disjoint fields, but they are only + // directly accessed in the body of the generator. + ty::TyGenerator(def, substs, _) if *drop_place == Place::Local(Local::new(1)) && !self.mir.upvar_decls.is_empty() => { substs.upvar_tys(def, self.tcx).enumerate() diff --git a/src/librustc_mir/borrow_check/nll/constraint_generation.rs b/src/librustc_mir/borrow_check/nll/constraint_generation.rs index d34e9434fbf2a..1191ee9f9fbc8 100644 --- a/src/librustc_mir/borrow_check/nll/constraint_generation.rs +++ b/src/librustc_mir/borrow_check/nll/constraint_generation.rs @@ -20,7 +20,7 @@ use rustc::mir::{BasicBlock, BasicBlockData, Location, Mir, Place, Rvalue}; use rustc::mir::{Local, PlaceProjection, ProjectionElem, Statement, Terminator}; use rustc::ty::fold::TypeFoldable; use rustc::ty::subst::Substs; -use rustc::ty::{self, CanonicalTy, ClosureSubsts}; +use rustc::ty::{self, CanonicalTy, ClosureSubsts, GeneratorSubsts}; use super::region_infer::{Cause, RegionInferenceContext}; use super::ToRegionVid; @@ -97,6 +97,13 @@ impl<'cg, 'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'gcx self.super_ty(ty); } + /// We sometimes have `generator_substs` within an rvalue, or within a + /// call. Make them live at the location where they appear. + fn visit_generator_substs(&mut self, substs: &GeneratorSubsts<'tcx>, location: Location) { + self.add_regular_live_constraint(*substs, location, Cause::LiveOther(location)); + self.super_generator_substs(substs); + } + /// We sometimes have `closure_substs` within an rvalue, or within a /// call. Make them live at the location where they appear. fn visit_closure_substs(&mut self, substs: &ClosureSubsts<'tcx>, location: Location) { 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 664d4214ca893..fbff17e589855 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/annotation.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/annotation.rs @@ -30,12 +30,11 @@ impl<'gcx, 'tcx> RegionInferenceContext<'tcx> { &substs.substs[..] )); } - DefiningTy::Generator(def_id, substs, interior, _) => { + DefiningTy::Generator(def_id, substs, _) => { err.note(&format!( - "defining type: {:?} with closure substs {:#?} and interior {:?}", + "defining type: {:?} with generator substs {:#?}", def_id, - &substs.substs[..], - interior + &substs.substs[..] )); } DefiningTy::FnDef(def_id, substs) => { diff --git a/src/librustc_mir/borrow_check/nll/renumber.rs b/src/librustc_mir/borrow_check/nll/renumber.rs index 04c206b5c0c40..7edee42b78ff7 100644 --- a/src/librustc_mir/borrow_check/nll/renumber.rs +++ b/src/librustc_mir/borrow_check/nll/renumber.rs @@ -9,7 +9,7 @@ // except according to those terms. use rustc::ty::subst::Substs; -use rustc::ty::{self, CanonicalTy, ClosureSubsts, GeneratorInterior, Ty, TypeFoldable}; +use rustc::ty::{self, CanonicalTy, ClosureSubsts, GeneratorSubsts, Ty, TypeFoldable}; use rustc::mir::{BasicBlock, Local, Location, Mir, Statement, StatementKind}; use rustc::mir::visit::{MutVisitor, TyContext}; use rustc::infer::{InferCtxt, NLLRegionVariableOrigin}; @@ -90,19 +90,19 @@ impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> { *constant = self.renumber_regions(ty_context, &*constant); } - fn visit_generator_interior(&mut self, - interior: &mut GeneratorInterior<'tcx>, - location: Location) { + fn visit_generator_substs(&mut self, + substs: &mut GeneratorSubsts<'tcx>, + location: Location) { debug!( - "visit_generator_interior(interior={:?}, location={:?})", - interior, + "visit_generator_substs(substs={:?}, location={:?})", + substs, location, ); let ty_context = TyContext::Location(location); - *interior = self.renumber_regions(ty_context, interior); + *substs = self.renumber_regions(ty_context, substs); - debug!("visit_generator_interior: interior={:?}", interior); + debug!("visit_generator_substs: substs={:?}", substs); } fn visit_closure_substs(&mut self, substs: &mut ClosureSubsts<'tcx>, location: Location) { 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 6c4c4a171efea..42a1745addff7 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 0e519a37e577e..52ebf38c668c2 100644 --- a/src/librustc_mir/borrow_check/nll/universal_regions.rs +++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs @@ -28,7 +28,7 @@ use rustc::infer::{InferCtxt, NLLRegionVariableOrigin}; use rustc::infer::region_constraints::GenericKind; use rustc::infer::outlives::bounds::{self, OutlivesBound}; use rustc::infer::outlives::free_region_map::FreeRegionRelations; -use rustc::ty::{self, RegionVid, Ty, TyCtxt}; +use rustc::ty::{self, RegionVid, Ty, TyCtxt, ClosureSubsts, GeneratorSubsts}; use rustc::ty::fold::TypeFoldable; use rustc::ty::subst::Substs; use rustc::util::nodemap::FxHashMap; @@ -116,10 +116,7 @@ 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>, - hir::GeneratorMovability), + Generator(DefId, ty::GeneratorSubsts<'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. @@ -511,8 +508,8 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> { ); let yield_ty = match defining_ty { - DefiningTy::Generator(def_id, substs, _, _) => { - Some(substs.generator_yield_ty(def_id, self.infcx.tcx)) + DefiningTy::Generator(def_id, substs, _) => { + Some(substs.yield_ty(def_id, self.infcx.tcx)) } _ => None, }; @@ -553,8 +550,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, movability) => { - DefiningTy::Generator(def_id, substs, interior, movability) + ty::TyGenerator(def_id, substs, movability) => { + DefiningTy::Generator(def_id, substs, movability) } ty::TyFnDef(def_id, substs) => DefiningTy::FnDef(def_id, substs), _ => span_bug!( @@ -590,7 +587,8 @@ 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(_, ClosureSubsts { ref substs }) | + DefiningTy::Generator(_, GeneratorSubsts { ref 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`. @@ -598,9 +596,9 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> { // `identity_substs`, we will get only those regions // that correspond to early-bound regions declared on // the `closure_base_def_id`. - assert!(substs.substs.len() >= identity_substs.len()); - assert_eq!(substs.substs.regions().count(), identity_substs.regions().count()); - substs.substs + assert!(substs.len() >= identity_substs.len()); + assert_eq!(substs.regions().count(), identity_substs.regions().count()); + substs } DefiningTy::FnDef(_, substs) | DefiningTy::Const(_, substs) => substs, @@ -651,10 +649,10 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> { ) } - DefiningTy::Generator(def_id, substs, interior, movability) => { + DefiningTy::Generator(def_id, substs, 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, movability); + let output = substs.return_ty(def_id, tcx); + let generator_ty = tcx.mk_generator(def_id, substs, 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 593c43e1ab40f..648746b6e9047 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -18,7 +18,7 @@ use build::expr::category::{Category, RvalueFunc}; use hair::*; use rustc::middle::const_val::ConstVal; use rustc::middle::region; -use rustc::ty::{self, Ty}; +use rustc::ty::{self, Ty, UpvarSubsts}; use rustc::mir::*; use rustc::mir::interpret::{Value, PrimVal, EvalErrorKind}; use syntax_pos::Span; @@ -185,28 +185,32 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { block.and(Rvalue::Aggregate(box AggregateKind::Tuple, fields)) } - ExprKind::Closure { closure_id, substs, upvars, interior } => { + ExprKind::Closure { closure_id, substs, upvars, movability } => { // 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, 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 { - span: expr_span, - ty: this.hir.tcx().types.u32, - literal: Literal::Value { - value: this.hir.tcx().mk_const(ty::Const { - val: ConstVal::Value(Value::ByVal(PrimVal::Bytes(0))), - ty: this.hir.tcx().types.u32 - }), - }, - })); - box AggregateKind::Generator(closure_id, substs, interior, movability) - } else { - box AggregateKind::Closure(closure_id, substs) + let result = match substs { + UpvarSubsts::Generator(substs) => { + 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. + operands.push(Operand::Constant(box Constant { + span: expr_span, + ty: this.hir.tcx().types.u32, + literal: Literal::Value { + value: this.hir.tcx().mk_const(ty::Const { + val: ConstVal::Value(Value::ByVal(PrimVal::Bytes(0))), + ty: this.hir.tcx().types.u32 + }), + }, + })); + box AggregateKind::Generator(closure_id, substs, movability) + } + UpvarSubsts::Closure(substs) => { + box AggregateKind::Closure(closure_id, substs) + } }; block.and(Rvalue::Aggregate(result, operands)) } diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index dd2a336af41d0..afbcf100b056a 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -130,7 +130,7 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t let (yield_ty, return_ty) = if body.is_generator { let gen_sig = match ty.sty { ty::TyGenerator(gen_def_id, gen_substs, ..) => - gen_substs.generator_sig(gen_def_id, tcx), + gen_substs.sig(gen_def_id, tcx), _ => span_bug!(tcx.hir.span(id), "generator w/o generator type: {:?}", ty), }; diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 966092ac5df06..249497538215d 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -470,10 +470,10 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, hir::ExprClosure(..) => { 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, movability) =>{ - (def_id, substs, Some((interior, movability))) + let (def_id, substs, movability) = match closure_ty.sty { + ty::TyClosure(def_id, substs) => (def_id, UpvarSubsts::Closure(substs), None), + ty::TyGenerator(def_id, substs, movability) => { + (def_id, UpvarSubsts::Generator(substs), Some(movability)) } _ => { span_bug!(expr.span, "closure expr w/o closure type: {:?}", closure_ty); @@ -489,7 +489,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, closure_id: def_id, substs, upvars, - interior, + movability, } } diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index 0b6a1e3f52db0..c27250267bbc8 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -18,7 +18,7 @@ use rustc::mir::{BinOp, BorrowKind, Field, Literal, UnOp}; use rustc::hir::def_id::DefId; use rustc::middle::region; use rustc::ty::subst::Substs; -use rustc::ty::{AdtDef, ClosureSubsts, Region, Ty, GeneratorInterior}; +use rustc::ty::{AdtDef, UpvarSubsts, Region, Ty}; use rustc::hir; use syntax::ast; use syntax_pos::Span; @@ -266,9 +266,9 @@ pub enum ExprKind<'tcx> { }, Closure { closure_id: DefId, - substs: ClosureSubsts<'tcx>, + substs: UpvarSubsts<'tcx>, upvars: Vec>, - interior: Option<(GeneratorInterior<'tcx>, hir::GeneratorMovability)>, + movability: Option, }, Literal { literal: Literal<'tcx>, diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 7b152bc12867d..44f9542e73394 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -18,7 +18,7 @@ use monomorphize::Instance; use rustc::hir; use rustc::hir::def_id::DefId; use rustc::session::config::OptLevel; -use rustc::ty::{self, Ty, TyCtxt}; +use rustc::ty::{self, Ty, TyCtxt, ClosureSubsts, GeneratorSubsts}; use rustc::ty::subst::Substs; use syntax::ast; use syntax::attr::InlineAttr; @@ -376,11 +376,11 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { self.push_type_name(sig.output(), output); } }, - ty::TyGenerator(def_id, ref closure_substs, _, _) | - ty::TyClosure(def_id, ref closure_substs) => { + ty::TyGenerator(def_id, GeneratorSubsts { ref substs }, _) | + ty::TyClosure(def_id, ClosureSubsts { ref substs }) => { self.push_def_path(def_id, output); let generics = self.tcx.generics_of(self.tcx.closure_base_def_id(def_id)); - let substs = closure_substs.substs.truncate_to(self.tcx, generics); + let substs = substs.truncate_to(self.tcx, generics); self.push_type_params(substs, iter::empty(), output); } ty::TyError | diff --git a/src/librustc_mir/monomorphize/mod.rs b/src/librustc_mir/monomorphize/mod.rs index 020dce62c3804..04d4f7a3968ee 100644 --- a/src/librustc_mir/monomorphize/mod.rs +++ b/src/librustc_mir/monomorphize/mod.rs @@ -84,8 +84,7 @@ fn fn_once_adapter_instance<'a, 'tcx>( .unwrap().def_id; let def = ty::InstanceDef::ClosureOnceShim { call_once }; - let self_ty = tcx.mk_closure_from_closure_substs( - closure_did, substs); + let self_ty = tcx.mk_closure(closure_did, substs); let sig = substs.closure_sig(closure_did, tcx); let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index a86e077927c0d..699a5b17435bd 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 32d68962a0d34..2bf5a49c97e8f 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/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs index dfa048e2e4bcf..cd5ebae2d9dfd 100644 --- a/src/librustc_mir/transform/erase_regions.rs +++ b/src/librustc_mir/transform/erase_regions.rs @@ -54,12 +54,6 @@ impl<'a, 'tcx> MutVisitor<'tcx> for EraseRegionsVisitor<'a, 'tcx> { *substs = self.tcx.erase_regions(substs); } - fn visit_closure_substs(&mut self, - substs: &mut ty::ClosureSubsts<'tcx>, - _: Location) { - *substs = self.tcx.erase_regions(substs); - } - fn visit_statement(&mut self, block: BasicBlock, statement: &mut Statement<'tcx>, diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 168f24f2cee2a..c4e700cdd1f41 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -64,7 +64,7 @@ use rustc::hir::def_id::DefId; use rustc::middle::const_val::ConstVal; use rustc::mir::*; use rustc::mir::visit::{PlaceContext, Visitor, MutVisitor}; -use rustc::ty::{self, TyCtxt, AdtDef, Ty, GeneratorInterior}; +use rustc::ty::{self, TyCtxt, AdtDef, Ty}; use rustc::ty::subst::Substs; use util::dump_mir; use util::liveness::{self, LivenessMode}; @@ -464,7 +464,7 @@ fn locals_live_across_suspend_points<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, source: MirSource, upvars: Vec>, - interior: GeneratorInterior<'tcx>, + interior: Ty<'tcx>, movable: bool, mir: &mut Mir<'tcx>) -> (HashMap, usize)>, @@ -479,7 +479,7 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Erase regions from the types passed in from typeck so we can compare them with // MIR types let allowed_upvars = tcx.erase_regions(&upvars); - let allowed = match interior.witness.sty { + let allowed = match interior.sty { ty::TyGeneratorWitness(s) => tcx.erase_late_bound_regions(&s), _ => bug!(), }; @@ -855,9 +855,9 @@ impl MirPass for StateTransform { // Get the interior types and substs which typeck computed let (upvars, interior, movable) = match gen_ty.sty { - ty::TyGenerator(_, substs, interior, movability) => { + ty::TyGenerator(_, substs, movability) => { (substs.upvar_tys(def_id, tcx).collect(), - interior, + substs.witness(def_id, tcx), movability == hir::GeneratorMovability::Movable) } _ => bug!(), diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 1c04fe170a16d..a641cf3d93ecf 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -780,14 +780,17 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> fn open_drop<'a>(&mut self) -> BasicBlock { let ty = self.place_ty(self.place); match ty.sty { - ty::TyClosure(def_id, substs) | + ty::TyClosure(def_id, substs) => { + let tys : Vec<_> = substs.upvar_tys(def_id, self.tcx()).collect(); + self.open_drop_for_tuple(&tys) + } // Note that `elaborate_drops` only drops the upvars of a generator, // and this is ok because `open_drop` here can only be reached // within that own generator's resume function. // 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 ddee5558c0fee..71012ca6d5f79 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -418,11 +418,10 @@ impl<'cx, 'gcx, 'tcx> Visitor<'tcx> for ExtraComments<'cx, 'gcx, 'tcx> { self.push(&format!("+ substs: {:#?}", substs)); } - AggregateKind::Generator(def_id, substs, interior, movability) => { + AggregateKind::Generator(def_id, substs, 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 8e4f82d2e1e1e..ce5707276ee1a 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, _movability) => { + ty::TyGenerator(def_id, substs, _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 004fb0f08f93d..75b56be3c162a 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -421,9 +421,9 @@ 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); + let sig = substs.poly_sig(def_id, cx.tcx); let env_region = ty::ReLateBound(ty::DebruijnIndex::new(1), ty::BrEnv); let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty); diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index a025057faaf3a..17a8196484f6b 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 ab01984aa0fcb..599fca9ffdd36 100644 --- a/src/librustc_trans/mir/mod.rs +++ b/src/librustc_trans/mir/mod.rs @@ -12,7 +12,7 @@ use common::{C_i32, C_null}; use libc::c_uint; use llvm::{self, ValueRef, BasicBlockRef}; use llvm::debuginfo::DIScope; -use rustc::ty::{self, Ty, TypeFoldable}; +use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts}; use rustc::ty::layout::{LayoutOf, TyLayout}; use rustc::mir::{self, Mir}; use rustc::ty::subst::Substs; @@ -575,11 +575,12 @@ fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>, _ => (arg.layout, false) }; - let upvar_tys = match closure_layout.ty.sty { - ty::TyClosure(def_id, substs) | - ty::TyGenerator(def_id, substs, _, _) => substs.upvar_tys(def_id, tcx), + let (def_id, upvar_substs) = match closure_layout.ty.sty { + ty::TyClosure(def_id, substs) => (def_id, UpvarSubsts::Closure(substs)), + ty::TyGenerator(def_id, substs, _) => (def_id, UpvarSubsts::Generator(substs)), _ => bug!("upvar_decls with non-closure arg0 type `{}`", closure_layout.ty) }; + let upvar_tys = upvar_substs.upvar_tys(def_id, tcx); // Store the pointer to closure data in an alloca for debuginfo // because that's what the llvm.dbg.declare intrinsic expects. diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index cbe66746a2966..94ef040d80a4f 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -113,23 +113,29 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { .next_ty_var(TypeVariableOrigin::ClosureSynthetic(expr.span)) }, ); - let substs = ty::ClosureSubsts { substs }; - let closure_type = self.tcx.mk_closure(expr_def_id, substs); - if let Some(GeneratorTypes { yield_ty, interior, movability }) = generator_types { + let substs = ty::GeneratorSubsts { substs }; self.demand_eqtype( expr.span, yield_ty, - substs.generator_yield_ty(expr_def_id, self.tcx), + substs.yield_ty(expr_def_id, self.tcx), ); self.demand_eqtype( expr.span, liberated_sig.output(), - substs.generator_return_ty(expr_def_id, self.tcx), + substs.return_ty(expr_def_id, self.tcx), ); - return self.tcx.mk_generator(expr_def_id, substs, interior, movability); + self.demand_eqtype( + expr.span, + interior, + substs.witness(expr_def_id, self.tcx), + ); + return self.tcx.mk_generator(expr_def_id, substs, movability); } + let substs = ty::ClosureSubsts { substs }; + let closure_type = self.tcx.mk_closure(expr_def_id, substs); + debug!( "check_closure: expr.id={:?} closure_type={:?}", expr.id, closure_type diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs index 7bae5fe4fd1af..b3d2a09a72cc7 100644 --- a/src/librustc_typeck/check/generator_interior.rs +++ b/src/librustc_typeck/check/generator_interior.rs @@ -17,7 +17,7 @@ use rustc::hir::def_id::DefId; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir::{self, Pat, PatKind, Expr}; use rustc::middle::region; -use rustc::ty::{self, Ty, GeneratorInterior}; +use rustc::ty::{self, Ty}; use rustc_data_structures::sync::Lrc; use syntax_pos::Span; use super::FnCtxt; @@ -85,7 +85,7 @@ impl<'a, 'gcx, 'tcx> InteriorVisitor<'a, 'gcx, 'tcx> { pub fn resolve_interior<'a, 'gcx, 'tcx>(fcx: &'a FnCtxt<'a, 'gcx, 'tcx>, def_id: DefId, body_id: hir::BodyId, - interior: GeneratorInterior<'tcx>) { + interior: Ty<'tcx>) { let body = fcx.tcx.hir.body(body_id); let mut visitor = InteriorVisitor { fcx, @@ -135,7 +135,7 @@ pub fn resolve_interior<'a, 'gcx, 'tcx>(fcx: &'a FnCtxt<'a, 'gcx, 'tcx>, witness, body.value.span); // Unify the type variable inside the generator with the new witness - match fcx.at(&fcx.misc(body.value.span), fcx.param_env).eq(interior.witness, witness) { + match fcx.at(&fcx.misc(body.value.span), fcx.param_env).eq(interior, witness) { Ok(ok) => fcx.register_infer_ok_obligations(ok), _ => bug!(), } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 25c226e4591f6..0cc1b62e83e34 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -208,7 +208,7 @@ pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { deferred_cast_checks: RefCell>>, - deferred_generator_interiors: RefCell)>>, + deferred_generator_interiors: RefCell)>>, // Anonymized types found in explicit return types and their // associated fresh inference variable. Writeback resolves these @@ -1009,7 +1009,7 @@ struct GeneratorTypes<'tcx> { yield_ty: ty::Ty<'tcx>, /// Types that are captured (see `GeneratorInterior` for more). - interior: ty::GeneratorInterior<'tcx>, + interior: ty::Ty<'tcx>, /// Indicates if the generator is movable or static (immovable) movability: hir::GeneratorMovability, @@ -1087,12 +1087,11 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, // This ensures that all nested generators appear before the entry of this generator. // 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 }; + let interior = fcx.next_ty_var(TypeVariableOrigin::MiscVariable(span)); fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior)); Some(GeneratorTypes { yield_ty: fcx.yield_ty.unwrap(), - interior: interior, + interior, movability: can_be_generator.unwrap(), }) } else { diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 5008b5d79bf41..6bede52b23963 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -46,7 +46,7 @@ use middle::expr_use_visitor as euv; use middle::mem_categorization as mc; use middle::mem_categorization::Categorization; use rustc::hir::def_id::DefId; -use rustc::ty::{self, Ty, TyCtxt}; +use rustc::ty::{self, Ty, TyCtxt, UpvarSubsts}; use rustc::infer::UpvarRegion; use syntax::ast; use syntax_pos::Span; @@ -74,11 +74,11 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for InferBorrowKindVisitor<'a, 'gcx, 'tcx> { fn visit_expr(&mut self, expr: &'gcx hir::Expr) { match expr.node { - hir::ExprClosure(cc, _, body_id, _, gen) => { + hir::ExprClosure(cc, _, body_id, _, _) => { let body = self.fcx.tcx.hir.body(body_id); self.visit_body(body); self.fcx - .analyze_closure(expr.id, expr.hir_id, expr.span, body, cc, gen); + .analyze_closure(expr.id, expr.hir_id, expr.span, body, cc); } _ => {} @@ -96,7 +96,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { span: Span, body: &hir::Body, capture_clause: hir::CaptureClause, - gen: Option, ) { /*! * Analysis starting point. @@ -109,9 +108,9 @@ 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), + let (closure_def_id, substs) = match self.node_ty(closure_hir_id).sty { + ty::TyClosure(def_id, substs) => (def_id, UpvarSubsts::Closure(substs)), + ty::TyGenerator(def_id, substs, _) => (def_id, UpvarSubsts::Generator(substs)), ref t => { span_bug!( span, @@ -122,10 +121,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } }; - let infer_kind = if gen.is_some() { - false + let infer_kind = if let UpvarSubsts::Closure(closure_substs) = substs{ + if self.closure_kind(closure_def_id, closure_substs).is_none() { + Some(closure_substs) + } else { + None + } } else { - self.closure_kind(closure_def_id, closure_substs).is_none() + None }; self.tcx.with_freevars(closure_node_id, |freevars| { @@ -173,7 +176,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { &self.tables.borrow(), ).consume_body(body); - if infer_kind { + if let Some(closure_substs) = infer_kind { // Unify the (as yet unbound) type variable in the closure // substs with the kind we inferred. let inferred_kind = delegate.current_closure_kind; @@ -209,14 +212,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Equate the type variables for the upvars with the actual types. let final_upvar_tys = self.final_upvar_tys(closure_node_id); debug!( - "analyze_closure: id={:?} closure_substs={:?} final_upvar_tys={:?}", + "analyze_closure: id={:?} substs={:?} final_upvar_tys={:?}", closure_node_id, - closure_substs, + substs, final_upvar_tys ); - for (upvar_ty, final_upvar_ty) in closure_substs - .upvar_tys(closure_def_id, self.tcx) - .zip(final_upvar_tys) + for (upvar_ty, final_upvar_ty) in substs.upvar_tys(closure_def_id, self.tcx) + .zip(final_upvar_tys) { self.demand_suptype(span, upvar_ty, final_upvar_ty); } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 1b8f2e661c30d..f0f392a2458e9 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -933,38 +933,36 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // provide junk type parameter defs - the only place that // cares about anything but the length is instantiation, // and we don't do that for closures. - if let NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) = node { - // add a dummy parameter for the closure kind - types.push(ty::TypeParameterDef { - index: type_start, - name: Symbol::intern("").as_interned_str(), - def_id, - has_default: false, - object_lifetime_default: rl::Set1::Empty, - pure_wrt_drop: false, - synthetic: None, - }); - - // add a dummy parameter for the closure signature - types.push(ty::TypeParameterDef { - index: type_start + 1, - name: Symbol::intern("").as_interned_str(), - def_id, - has_default: false, - object_lifetime_default: rl::Set1::Empty, - pure_wrt_drop: false, - synthetic: None, - }); + if let NodeExpr(&hir::Expr { node: hir::ExprClosure(.., gen), .. }) = node { + let dummy_args = if gen.is_some() { + &["", "", ""][..] + } else { + &["", ""][..] + }; - tcx.with_freevars(node_id, |fv| { - types.extend(fv.iter().zip(2..).map(|(_, i)| ty::TypeParameterDef { - index: type_start + i, - name: Symbol::intern("").as_interned_str(), + for (i, &arg) in dummy_args.iter().enumerate() { + types.push(ty::TypeParameterDef { + index: type_start + i as u32, + name: Symbol::intern(arg).as_interned_str(), def_id, has_default: false, object_lifetime_default: rl::Set1::Empty, pure_wrt_drop: false, synthetic: None, + }); + } + + tcx.with_freevars(node_id, |fv| { + types.extend(fv.iter().zip((dummy_args.len() as u32)..).map(|(_, i)| { + ty::TypeParameterDef { + index: type_start + i, + name: Symbol::intern("").as_interned_str(), + def_id, + has_default: false, + object_lifetime_default: rl::Set1::Empty, + pure_wrt_drop: false, + synthetic: None, + } })); }); }