Store the GeneratorInterior in the new GeneratorSubsts

This commit is contained in:
John Kåre Alsaker 2018-05-02 13:14:30 +02:00
parent 0edc8f4270
commit 710b4ad2a5
51 changed files with 357 additions and 308 deletions

View file

@ -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);
}
}

View file

@ -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<StableHashingContex
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
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);
}

View file

@ -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<usize>),
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)
}
}

View file

@ -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)
}
}
}

View file

@ -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,

View file

@ -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<N>
@ -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(),
}),

View file

@ -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

View file

@ -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

View file

@ -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>
}

View file

@ -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>>>) -> Ty<'tcx> {

View file

@ -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) => {

View file

@ -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) => {

View file

@ -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);

View file

@ -369,7 +369,7 @@ pub fn characteristic_def_id_of_type(ty: Ty) -> Option<DefId> {
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 |

View file

@ -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::<Result<Vec<_>, _>>()?,
&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()
}

View file

@ -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};

View file

@ -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);

View file

@ -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 })
}
}

View file

@ -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<Self::Lifted> {
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<Self::Lifted> {
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,
}
}

View file

@ -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<Item=Ty<'tcx>> + '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<Item=Ty<'tcx>> + '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()

View file

@ -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),

View file

@ -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) => {

View file

@ -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)))

View file

@ -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

View file

@ -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()

View file

@ -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) {

View file

@ -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) => {

View file

@ -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) {

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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))
}

View file

@ -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),
};

View file

@ -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,
}
}

View file

@ -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<ExprRef<'tcx>>,
interior: Option<(GeneratorInterior<'tcx>, hir::GeneratorMovability)>,
movability: Option<hir::GeneratorMovability>,
},
Literal {
literal: Literal<'tcx>,

View file

@ -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 |

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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>,

View file

@ -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<Ty<'tcx>>,
interior: GeneratorInterior<'tcx>,
interior: Ty<'tcx>,
movable: bool,
mir: &mut Mir<'tcx>)
-> (HashMap<Local, (Ty<'tcx>, 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!(),

View file

@ -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)
}

View file

@ -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));
}

View file

@ -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).

View file

@ -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);

View file

@ -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();

View file

@ -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.

View file

@ -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

View file

@ -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!(),
}

View file

@ -208,7 +208,7 @@ pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
deferred_generator_interiors: RefCell<Vec<(hir::BodyId, ty::GeneratorInterior<'tcx>)>>,
deferred_generator_interiors: RefCell<Vec<(hir::BodyId, Ty<'tcx>)>>,
// 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 {

View file

@ -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<hir::GeneratorMovability>,
) {
/*!
* 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);
}

View file

@ -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("<closure_kind>").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() {
&["<yield_ty>", "<return_ty>", "<witness>"][..]
} else {
&["<closure_kind>", "<closure_signature>"][..]
};
// add a dummy parameter for the closure signature
types.push(ty::TypeParameterDef {
index: type_start + 1,
name: Symbol::intern("<closure_signature>").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(2..).map(|(_, i)| ty::TypeParameterDef {
index: type_start + i,
name: Symbol::intern("<upvar>").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("<upvar>").as_interned_str(),
def_id,
has_default: false,
object_lifetime_default: rl::Set1::Empty,
pure_wrt_drop: false,
synthetic: None,
}
}));
});
}