From 0edc8f4270589002fe12b9de9a2bd2b1220feb4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 2 May 2018 10:17:12 +0200 Subject: [PATCH] Store generator movability outside GeneratorInterior --- src/librustc/ich/impls_mir.rs | 3 ++- src/librustc/ich/impls_ty.rs | 5 +++-- src/librustc/mir/mod.rs | 11 ++++++----- src/librustc/mir/tcx.rs | 4 ++-- src/librustc/mir/visit.rs | 5 +++-- src/librustc/traits/select.rs | 4 ++-- src/librustc/ty/context.rs | 5 +++-- src/librustc/ty/fast_reject.rs | 2 +- src/librustc/ty/flags.rs | 2 +- src/librustc/ty/item_path.rs | 2 +- src/librustc/ty/layout.rs | 4 ++-- src/librustc/ty/outlives.rs | 2 +- src/librustc/ty/relate.rs | 9 ++++----- src/librustc/ty/structural_impls.rs | 14 +++++++++----- src/librustc/ty/sty.rs | 5 ++--- src/librustc/ty/util.rs | 2 +- src/librustc/ty/walk.rs | 2 +- src/librustc/util/ppaux.rs | 4 ++-- .../borrow_check/error_reporting.rs | 2 +- .../nll/region_infer/annotation.rs | 2 +- .../borrow_check/nll/type_check/mod.rs | 6 +++--- .../borrow_check/nll/universal_regions.rs | 19 +++++++++++-------- src/librustc_mir/build/expr/as_rvalue.rs | 7 ++++--- src/librustc_mir/hair/cx/expr.rs | 4 +++- src/librustc_mir/hair/mod.rs | 2 +- src/librustc_mir/monomorphize/item.rs | 2 +- src/librustc_mir/shim.rs | 2 +- src/librustc_mir/transform/check_unsafety.rs | 2 +- src/librustc_mir/transform/generator.rs | 19 ++++++++++++++----- src/librustc_mir/util/elaborate_drops.rs | 2 +- src/librustc_mir/util/pretty.rs | 3 ++- src/librustc_traits/dropck_outlives.rs | 2 +- src/librustc_trans/common.rs | 2 +- src/librustc_trans/debuginfo/metadata.rs | 2 +- src/librustc_trans/mir/mod.rs | 2 +- src/librustc_typeck/check/closure.rs | 4 ++-- src/librustc_typeck/check/mod.rs | 16 ++++++++++------ src/librustc_typeck/check/upvar.rs | 3 ++- 38 files changed, 108 insertions(+), 80 deletions(-) diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index 33f43e53394f5..29a0632511c32 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 a40d8e0927740..96ef8591645aa 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 37f6d47ff849d..907ffc6760605 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), 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 20902d9111019..33af199d75888 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 59b6f3697541a..6aed5076c1f16 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 54b2cf2808282..82643c315b99d 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 3d154e43a9ae1..6ed243361c093 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> { diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs index 31b3ca44700e9..2b6901f74def9 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 086fc66c70f9d..acc17a08a80d7 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 752b7f69a6a7f..b58c4138597d2 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 02c4b73efa146..7b91040b8e7de 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/outlives.rs b/src/librustc/ty/outlives.rs index ff99a4b7ff638..4eb736789f3cd 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 03ed6e7ac90d1..ed0835418a484 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 d4ed6c60e0efa..6df3b5dc2bd1f 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 { 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 382db571b524e..b2c715bf7b976 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 4aa70e1f7e006..12421715ed56e 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 46c048e839b4b..d3fa376d6a889 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 894a18b79ccb2..770357e549d7d 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 db2e078586eda..f68c164751d6f 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 d213f376d2bca..664d4214ca893 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 42a1745addff7..6c4c4a171efea 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 0fe6265345de1..0e519a37e577e 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 9e96fdf821417..593c43e1ab40f 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 d0c352319c8c5..966092ac5df06 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 fe82b8158f76d..0b6a1e3f52db0 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>, - interior: Option>, + 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 9e43bed1b63af..7b152bc12867d 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 699a5b17435bd..a86e077927c0d 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 2bf5a49c97e8f..32d68962a0d34 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 36735586e8117..168f24f2cee2a 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>, interior: GeneratorInterior<'tcx>, + movable: bool, mir: &mut Mir<'tcx>) -> (HashMap, 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 4b7c581d3c8ff..1c04fe170a16d 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 a891e372ad8b5..ddee5558c0fee 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 ba31ce2692fbc..8e4f82d2e1e1e 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 4a0619b23360d..004fb0f08f93d 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 f16fef5ec1e84..a025057faaf3a 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 a074f25dfc9ba..ab01984aa0fcb 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 3b9d561ffc5a5..cbe66746a2966 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 db859e42057e9..25c226e4591f6 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 58dc5839578f7..5008b5d79bf41 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,