diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index 33f43e53394f5..c71b10ce142c5 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -483,10 +483,10 @@ 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, 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..d0d0ab093c87f 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, movable }); +impl_stable_hash_for!(struct ty::GeneratorSubsts<'tcx> { substs }); impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> { parent, @@ -889,9 +888,10 @@ for ty::TypeVariants<'gcx> TyRawPtr(pointee_ty) => { pointee_ty.hash_stable(hcx, hasher); } - TyRef(region, pointee_ty) => { + TyRef(region, pointee_ty, mutbl) => { region.hash_stable(hcx, hasher); pointee_ty.hash_stable(hcx, hasher); + mutbl.hash_stable(hcx, hasher); } TyFnDef(def_id, substs) => { def_id.hash_stable(hcx, hasher); @@ -908,10 +908,10 @@ 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, 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) => { types.hash_stable(hcx, hasher) @@ -1315,11 +1315,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/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 588f75f809c15..da93156b0b0bd 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -665,7 +665,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fn push_ty_ref<'tcx>( r: &ty::Region<'tcx>, - tnm: &ty::TypeAndMut<'tcx>, + ty: Ty<'tcx>, + mutbl: hir::Mutability, s: &mut DiagnosticStyledString, ) { let r = &format!("{}", r); @@ -673,13 +674,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { "&{}{}{}", r, if r == "" { "" } else { " " }, - if tnm.mutbl == hir::MutMutable { + if mutbl == hir::MutMutable { "mut " } else { "" } )); - s.push_normal(format!("{}", tnm.ty)); + s.push_normal(format!("{}", ty)); } match (&t1.sty, &t2.sty) { @@ -803,24 +804,25 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } // When finding T != &T, highlight only the borrow - (&ty::TyRef(r1, ref tnm1), _) if equals(&tnm1.ty, &t2) => { + (&ty::TyRef(r1, ref_ty1, mutbl1), _) if equals(&ref_ty1, &t2) => { let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new()); - push_ty_ref(&r1, tnm1, &mut values.0); + push_ty_ref(&r1, ref_ty1, mutbl1, &mut values.0); values.1.push_normal(format!("{}", t2)); values } - (_, &ty::TyRef(r2, ref tnm2)) if equals(&t1, &tnm2.ty) => { + (_, &ty::TyRef(r2, ref_ty2, mutbl2)) if equals(&t1, &ref_ty2) => { let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new()); values.0.push_normal(format!("{}", t1)); - push_ty_ref(&r2, tnm2, &mut values.1); + push_ty_ref(&r2, ref_ty2, mutbl2, &mut values.1); values } // When encountering &T != &mut T, highlight only the borrow - (&ty::TyRef(r1, ref tnm1), &ty::TyRef(r2, ref tnm2)) if equals(&tnm1.ty, &tnm2.ty) => { + (&ty::TyRef(r1, ref_ty1, mutbl1), + &ty::TyRef(r2, ref_ty2, mutbl2)) if equals(&ref_ty1, &ref_ty2) => { let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new()); - push_ty_ref(&r1, tnm1, &mut values.0); - push_ty_ref(&r2, tnm2, &mut values.1); + push_ty_ref(&r1, ref_ty1, mutbl1, &mut values.0); + push_ty_ref(&r2, ref_ty2, mutbl2, &mut values.1); values } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 725fcf1e6463b..614ae17fa4692 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -456,7 +456,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { // make sure that the thing we are pointing out stays valid // for the lifetime `scope_r` of the resulting ptr: let expr_ty = return_if_err!(self.mc.expr_ty(expr)); - if let ty::TyRef(r, _) = expr_ty.sty { + if let ty::TyRef(r, _, _) = expr_ty.sty { let bk = ty::BorrowKind::from_mutbl(m); self.borrow_expr(&base, r, bk, AddrOf); } @@ -859,7 +859,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { // It is also a borrow or copy/move of the value being matched. match bm { ty::BindByReference(m) => { - if let ty::TyRef(r, _) = pat_ty.sty { + if let ty::TyRef(r, _, _) = pat_ty.sty { let bk = ty::BorrowKind::from_mutbl(m); delegate.borrow(pat.id, pat.span, &cmt_pat, r, bk, RefBinding); } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index f40a41cd29924..3875770a5ff5c 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -1012,7 +1012,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { let base_ty = self.expr_ty_adjusted(base)?; let (region, mutbl) = match base_ty.sty { - ty::TyRef(region, mt) => (region, mt.mutbl), + ty::TyRef(region, _, mutbl) => (region, mutbl), _ => { span_bug!(expr.span, "cat_overloaded_place: base is not a reference") } @@ -1046,8 +1046,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { let ptr = match base_cmt.ty.sty { ty::TyAdt(def, ..) if def.is_box() => Unique, ty::TyRawPtr(ref mt) => UnsafePtr(mt.mutbl), - ty::TyRef(r, mt) => { - let bk = ty::BorrowKind::from_mutbl(mt.mutbl); + ty::TyRef(r, _, mutbl) => { + let bk = ty::BorrowKind::from_mutbl(mutbl); if implicit { Implicit(bk, r) } else { BorrowedPtr(bk, r) } } ref ty => bug!("unexpected type in cat_deref: {:?}", ty) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 37f6d47ff849d..11e25322f0072 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -27,9 +27,8 @@ 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; use std::slice; use hir::{self, InlineAsm}; @@ -1641,7 +1640,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, GeneratorSubsts<'tcx>, hir::GeneratorMovability), } #[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)] @@ -1905,9 +1904,8 @@ pub fn print_miri_value(value: Value, ty: Ty, f: &mut W) -> fmt::Resul write!(f, "{:?}", ::std::char::from_u32(n as u32).unwrap()), (Value::ByVal(PrimVal::Undef), &TyFnDef(did, _)) => write!(f, "{}", item_path_str(did)), - (Value::ByValPair(PrimVal::Ptr(ptr), PrimVal::Bytes(len)), &TyRef(_, TypeAndMut { - ty: &ty::TyS { sty: TyStr, .. }, .. - })) => { + (Value::ByValPair(PrimVal::Ptr(ptr), PrimVal::Bytes(len)), + &TyRef(_, &ty::TyS { sty: TyStr, .. }, _)) => { ty::tls::with(|tcx| { let alloc = tcx .interpret_interner @@ -2375,10 +2373,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) => - AggregateKind::Generator(id, - substs.fold_with(folder), - interior.fold_with(folder)), + AggregateKind::Generator(id, substs, movablity) => + AggregateKind::Generator(id, substs.fold_with(folder), movablity), }; Aggregate(kind, fields.fold_with(folder)) } @@ -2405,8 +2401,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 20902d9111019..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) => { - tcx.mk_generator(did, substs, interior) + 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 59b6f3697541a..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,11 +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); } } @@ -786,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/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 047d4bb893096..25be4a2ff5c8b 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -878,9 +878,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let mut trait_type = trait_ref.self_ty(); for refs_remaining in 0..refs_number { - if let ty::TypeVariants::TyRef(_, ty::TypeAndMut{ ty: t_type, mutbl: _ }) = - trait_type.sty { - + if let ty::TypeVariants::TyRef(_, t_type, _) = trait_type.sty { trait_type = t_type; let substs = self.tcx.mk_substs_trait(trait_type, &[]); 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 54b2cf2808282..614cb912fb212 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2167,14 +2167,14 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ty::TyUint(_) | ty::TyInt(_) | ty::TyBool | ty::TyFloat(_) | ty::TyChar | ty::TyRawPtr(..) | ty::TyNever | - ty::TyRef(_, ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => { + ty::TyRef(_, _, hir::MutImmutable) => { // Implementations provided in libcore None } ty::TyDynamic(..) | ty::TyStr | ty::TySlice(..) | ty::TyGenerator(..) | ty::TyGeneratorWitness(..) | ty::TyForeign(..) | - ty::TyRef(_, ty::TypeAndMut { ty: _, mutbl: hir::MutMutable }) => { + ty::TyRef(_, _, hir::MutMutable) => { Never } @@ -2263,7 +2263,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } ty::TyRawPtr(ty::TypeAndMut { ty: element_ty, ..}) | - ty::TyRef(_, ty::TypeAndMut { ty: element_ty, ..}) => { + ty::TyRef(_, element_ty, _) => { vec![element_ty] }, @@ -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 { + 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/cast.rs b/src/librustc/ty/cast.rs index 3ba79d91964ab..908335424e713 100644 --- a/src/librustc/ty/cast.rs +++ b/src/librustc/ty/cast.rs @@ -36,9 +36,9 @@ pub enum CastTy<'tcx> { /// Function Pointers FnPtr, /// Raw pointers - Ptr(&'tcx ty::TypeAndMut<'tcx>), + Ptr(ty::TypeAndMut<'tcx>), /// References - RPtr(&'tcx ty::TypeAndMut<'tcx>), + RPtr(ty::TypeAndMut<'tcx>), } /// Cast Kind. See RFC 401 (or librustc_typeck/check/cast.rs) @@ -69,8 +69,8 @@ impl<'tcx> CastTy<'tcx> { ty::TyFloat(_) => Some(CastTy::Float), ty::TyAdt(d,_) if d.is_enum() && d.is_payloadfree() => Some(CastTy::Int(IntTy::CEnum)), - ty::TyRawPtr(ref mt) => Some(CastTy::Ptr(mt)), - ty::TyRef(_, ref mt) => Some(CastTy::RPtr(mt)), + ty::TyRawPtr(mt) => Some(CastTy::Ptr(mt)), + ty::TyRef(_, ty, mutbl) => Some(CastTy::RPtr(ty::TypeAndMut { ty, mutbl })), ty::TyFnPtr(..) => Some(CastTy::FnPtr), _ => None, } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 3d154e43a9ae1..36eb091cb6e5b 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}; @@ -2351,7 +2351,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn mk_ref(self, r: Region<'tcx>, tm: TypeAndMut<'tcx>) -> Ty<'tcx> { - self.mk_ty(TyRef(r, tm)) + self.mk_ty(TyRef(r, tm.ty, tm.mutbl)) } pub fn mk_mut_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { @@ -2436,26 +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)) + 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/error.rs b/src/librustc/ty/error.rs index cf2004a681e62..cfde35de93c3b 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -189,20 +189,17 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { } ty::TySlice(_) => "slice".to_string(), ty::TyRawPtr(_) => "*-ptr".to_string(), - ty::TyRef(region, tymut) => { + ty::TyRef(region, ty, mutbl) => { + let tymut = ty::TypeAndMut { ty, mutbl }; let tymut_string = tymut.to_string(); if tymut_string == "_" || //unknown type name, tymut_string.len() > 10 || //name longer than saying "reference", region.to_string() != "" //... or a complex type { - match tymut { - ty::TypeAndMut{mutbl, ..} => { - format!("{}reference", match mutbl { - hir::Mutability::MutMutable => "mutable ", - _ => "" - }) - } - } + format!("{}reference", match mutbl { + hir::Mutability::MutMutable => "mutable ", + _ => "" + }) } else { format!("&{}", tymut_string) } diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs index 31b3ca44700e9..cf5e55a59f713 100644 --- a/src/librustc/ty/fast_reject.rs +++ b/src/librustc/ty/fast_reject.rs @@ -80,11 +80,11 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, ty::TyDynamic(ref trait_info, ..) => { trait_info.principal().map(|p| TraitSimplifiedType(p.def_id())) } - ty::TyRef(_, mt) => { + ty::TyRef(_, ty, _) => { // since we introduce auto-refs during method lookup, we // just treat &T and T as equivalent from the point of // view of possibly unifying - simplify_type(tcx, mt.ty, can_simplify_params) + simplify_type(tcx, ty, can_simplify_params) } ty::TyFnDef(def_id, _) | ty::TyClosure(def_id, _) => { diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index 086fc66c70f9d..01de848e0f076 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) => { @@ -174,9 +173,9 @@ impl FlagComputation { self.add_ty(m.ty); } - &ty::TyRef(r, ref m) => { + &ty::TyRef(r, ty, _) => { self.add_region(r); - self.add_ty(m.ty); + self.add_ty(ty); } &ty::TyTuple(ref ts) => { diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs index 325f8575fd0a7..17a3d0011eddf 100644 --- a/src/librustc/ty/inhabitedness/mod.rs +++ b/src/librustc/ty/inhabitedness/mod.rs @@ -269,8 +269,8 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { _ => DefIdForest::empty() } } - TyRef(_, ref tm) => { - tm.ty.uninhabited_from(visited, tcx) + TyRef(_, ty, _) => { + ty.uninhabited_from(visited, tcx) } _ => DefIdForest::empty(), 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 752b7f69a6a7f..41625afec86a0 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -360,8 +360,9 @@ pub fn characteristic_def_id_of_type(ty: Ty) -> Option { ty::TyArray(subty, _) | ty::TySlice(subty) => characteristic_def_id_of_type(subty), - ty::TyRawPtr(mt) | - ty::TyRef(_, mt) => characteristic_def_id_of_type(mt.ty), + ty::TyRawPtr(mt) => characteristic_def_id_of_type(mt.ty), + + ty::TyRef(_, ty, _) => characteristic_def_id_of_type(ty), ty::TyTuple(ref tys) => tys.iter() .filter_map(|ty| characteristic_def_id_of_type(ty)) diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 02c4b73efa146..0688dcabe5585 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -501,7 +501,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { } // Potentially-fat pointers. - ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) | + ty::TyRef(_, pointee, _) | ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => { let mut data_ptr = scalar_unit(Pointer); if !ty.is_unsafe_ptr() { @@ -1262,7 +1262,7 @@ impl<'a, 'tcx> SizeSkeleton<'tcx> { }; match ty.sty { - ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) | + ty::TyRef(_, pointee, _) | ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => { let non_zero = !ty.is_unsafe_ptr(); let tail = tcx.struct_tail(pointee); @@ -1560,7 +1560,7 @@ impl<'a, 'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx> } // Potentially-fat pointers. - ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) | + ty::TyRef(_, pointee, _) | ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => { assert!(i < 2); diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index c4fe112a9e913..7076112e3715a 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}; @@ -514,7 +514,7 @@ impl<'tcx> TyS<'tcx> { TypeVariants::TyInfer(InferTy::FloatVar(_)) | TypeVariants::TyInfer(InferTy::FreshIntTy(_)) | TypeVariants::TyInfer(InferTy::FreshFloatTy(_)) => true, - TypeVariants::TyRef(_, x) => x.ty.is_primitive_ty(), + TypeVariants::TyRef(_, x, _) => x.is_primitive_ty(), _ => false, } } diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 03ed6e7ac90d1..109dfebf154de 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), - &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)) + 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)) => @@ -455,10 +454,12 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R, Ok(tcx.mk_ptr(mt)) } - (&ty::TyRef(a_r, ref a_mt), &ty::TyRef(b_r, ref b_mt)) => + (&ty::TyRef(a_r, a_ty, a_mutbl), &ty::TyRef(b_r, b_ty, b_mutbl)) => { let r = relation.relate_with_variance(ty::Contravariant, &a_r, &b_r)?; - let mt = relation.relate(a_mt, b_mt)?; + let a_mt = ty::TypeAndMut { ty: a_ty, mutbl: a_mutbl }; + let b_mt = ty::TypeAndMut { ty: b_ty, mutbl: b_mutbl }; + let mt = relation.relate(&a_mt, &b_mt)?; Ok(tcx.mk_ref(r, mt)) } @@ -607,20 +608,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 { - assert_eq!(a.movable, b.movable); - let witness = relation.relate(&a.witness, &b.witness)?; - Ok(ty::GeneratorInterior { witness, movable: a.movable }) + 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 d4ed6c60e0efa..e77ede72143b1 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, movable: self.movable } + tcx.lift(&self.substs).map(|substs| { + ty::GeneratorSubsts { substs } }) } } @@ -864,11 +864,14 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { ty::TyFnDef(def_id, substs.fold_with(folder)) } ty::TyFnPtr(f) => ty::TyFnPtr(f.fold_with(folder)), - ty::TyRef(ref r, tm) => { - ty::TyRef(r.fold_with(folder), tm.fold_with(folder)) + ty::TyRef(ref r, ty, mutbl) => { + ty::TyRef(r.fold_with(folder), ty.fold_with(folder), mutbl) } - ty::TyGenerator(did, substs, interior) => { - ty::TyGenerator(did, substs.fold_with(folder), interior.fold_with(folder)) + ty::TyGenerator(did, substs, movability) => { + ty::TyGenerator( + did, + substs.fold_with(folder), + movability) } ty::TyGeneratorWitness(types) => ty::TyGeneratorWitness(types.fold_with(folder)), ty::TyClosure(did, substs) => ty::TyClosure(did, substs.fold_with(folder)), @@ -901,9 +904,9 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { ty::TyTuple(ts) => ts.visit_with(visitor), 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::TyRef(r, ty, _) => r.visit_with(visitor) || ty.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), @@ -980,8 +983,8 @@ BraceStructTypeFoldableImpl! { } BraceStructTypeFoldableImpl! { - impl<'tcx> TypeFoldable<'tcx> for ty::GeneratorInterior<'tcx> { - witness, movable, + impl<'tcx> TypeFoldable<'tcx> for ty::GeneratorSubsts<'tcx> { + substs, } } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 382db571b524e..7518f008fb316 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -121,7 +121,7 @@ pub enum TypeVariants<'tcx> { /// A reference; a pointer with an associated lifetime. Written as /// `&'a mut T` or `&'a T`. - TyRef(Region<'tcx>, TypeAndMut<'tcx>), + TyRef(Region<'tcx>, Ty<'tcx>, hir::Mutability), /// The anonymous type of a function declaration/definition. Each /// function has a unique type. @@ -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, 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,15 +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>, - pub movable: bool, +#[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)] @@ -1332,7 +1392,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { pub fn is_slice(&self) -> bool { match self.sty { - TyRawPtr(mt) | TyRef(_, mt) => match mt.ty.sty { + TyRawPtr(TypeAndMut { ty, .. }) | TyRef(_, ty, _) => match ty.sty { TySlice(_) | TyStr => true, _ => false, }, @@ -1381,11 +1441,8 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { pub fn is_mutable_pointer(&self) -> bool { match self.sty { - TyRawPtr(tnm) | TyRef(_, tnm) => if let hir::Mutability::MutMutable = tnm.mutbl { - true - } else { - false - }, + TyRawPtr(TypeAndMut { mutbl: hir::Mutability::MutMutable, .. }) | + TyRef(_, _, hir::Mutability::MutMutable) => true, _ => false } } @@ -1538,7 +1595,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { mutbl: hir::MutImmutable, }) }, - TyRef(_, mt) => Some(mt), + TyRef(_, ty, mutbl) => Some(TypeAndMut { ty, mutbl }), TyRawPtr(mt) if explicit => Some(mt), _ => None, } @@ -1592,7 +1649,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { /// ignores late-bound regions binders. pub fn regions(&self) -> Vec> { match self.sty { - TyRef(region, _) => { + TyRef(region, _, _) => { vec![region] } TyDynamic(ref obj, region) => { @@ -1605,8 +1662,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 4aa70e1f7e006..80dc3b2b452ce 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -201,7 +201,7 @@ impl<'tcx> ty::ParamEnv<'tcx> { // Now libcore provides that impl. ty::TyUint(_) | ty::TyInt(_) | ty::TyBool | ty::TyFloat(_) | ty::TyChar | ty::TyRawPtr(..) | ty::TyNever | - ty::TyRef(_, ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => return Ok(()), + ty::TyRef(_, _, hir::MutImmutable) => return Ok(()), ty::TyAdt(adt, substs) => (adt, substs), @@ -664,8 +664,8 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W> _ => bug!("arrays should not have {:?} as length", n) } } - TyRawPtr(m) | - TyRef(_, m) => self.hash(m.mutbl), + TyRawPtr(m) => self.hash(m.mutbl), + TyRef(_, _, mutbl) => self.hash(mutbl), TyClosure(def_id, _) | TyGenerator(def_id, _, _) | TyAnon(def_id, _) | @@ -1141,7 +1141,7 @@ impl<'tcx> ExplicitSelf<'tcx> { match self_arg_ty.sty { _ if is_self_ty(self_arg_ty) => ByValue, - ty::TyRef(region, ty::TypeAndMut { ty, mutbl }) if is_self_ty(ty) => { + ty::TyRef(region, ty, mutbl) if is_self_ty(ty) => { ByReference(region, mutbl) } ty::TyRawPtr(ty::TypeAndMut { ty, mutbl }) if is_self_ty(ty) => { diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs index 46c048e839b4b..ebe88d60ed12f 100644 --- a/src/librustc/ty/walk.rs +++ b/src/librustc/ty/walk.rs @@ -92,9 +92,12 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) { ty::TySlice(ty) => { stack.push(ty); } - ty::TyRawPtr(ref mt) | ty::TyRef(_, ref mt) => { + ty::TyRawPtr(ref mt) => { stack.push(mt.ty); } + ty::TyRef(_, ty, _) => { + stack.push(ty); + } ty::TyProjection(ref data) => { stack.extend(data.substs.types().rev()); } @@ -118,8 +121,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/ty/wf.rs b/src/librustc/ty/wf.rs index aea84791fe86b..62fed1ecb668a 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -298,9 +298,9 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { self.out.extend(obligations); } - ty::TyRef(r, mt) => { + ty::TyRef(r, rty, _) => { // WfReference - if !r.has_escaping_regions() && !mt.ty.has_escaping_regions() { + if !r.has_escaping_regions() && !rty.has_escaping_regions() { let cause = self.cause(traits::ReferenceOutlivesReferent(ty)); self.out.push( traits::Obligation::new( @@ -308,7 +308,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { param_env, ty::Predicate::TypeOutlives( ty::Binder::dummy( - ty::OutlivesPredicate(mt.ty, r))))); + ty::OutlivesPredicate(rty, r))))); } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 894a18b79ccb2..4fb1017035168 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 { @@ -1019,14 +1011,14 @@ define_print! { })?; tm.ty.print(f, cx) } - TyRef(r, ref tm) => { + TyRef(r, ty, mutbl) => { write!(f, "&")?; let s = r.print_to_string(cx); write!(f, "{}", s)?; if !s.is_empty() { write!(f, " ")?; } - tm.print(f, cx) + ty::TypeAndMut { ty, mutbl }.print(f, cx) } TyNever => write!(f, "!"), TyTuple(ref tys) => { @@ -1110,9 +1102,10 @@ define_print! { }) } TyStr => write!(f, "str"), - TyGenerator(did, substs, interior) => ty::tls::with(|tcx| { + TyGenerator(did, substs, movability) => ty::tls::with(|tcx| { let upvar_tys = substs.upvar_tys(did, tcx); - if interior.movable { + let witness = substs.witness(did, tcx); + if movability == hir::GeneratorMovability::Movable { write!(f, "[generator")?; } else { write!(f, "[static generator")?; @@ -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_lint/builtin.rs b/src/librustc_lint/builtin.rs index 7ae13c803ddca..5102bfe766eef 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1173,9 +1173,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes { let msg = "mutating transmuted &mut T from &T may cause undefined behavior, \ consider instead using an UnsafeCell"; match get_transmute_from_to(cx, expr) { - Some((&ty::TyRef(_, from_mt), &ty::TyRef(_, to_mt))) => { - if to_mt.mutbl == hir::Mutability::MutMutable && - from_mt.mutbl == hir::Mutability::MutImmutable { + Some((&ty::TyRef(_, _, from_mt), &ty::TyRef(_, _, to_mt))) => { + if to_mt == hir::Mutability::MutMutable && + from_mt == hir::Mutability::MutImmutable { cx.span_lint(MUTABLE_TRANSMUTES, expr.span, msg); } } diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 9e0dc4d80c8e2..32963146893bb 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -662,8 +662,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { help: Some("consider using a struct instead"), }, - ty::TyRawPtr(ref m) | - ty::TyRef(_, ref m) => self.check_type_for_ffi(cache, m.ty), + ty::TyRawPtr(ty::TypeAndMut { ty, .. }) | + ty::TyRef(_, ty, _) => self.check_type_for_ffi(cache, ty), ty::TyArray(ty, _) => self.check_type_for_ffi(cache, ty), diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index db2e078586eda..fde740bce3f35 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -773,8 +773,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { format!("{}", def.non_enum_variant().fields[field.index()].name) }, ty::TyTuple(_) => format!("{}", field.index()), - ty::TyRef(_, tnm) | ty::TyRawPtr(tnm) => { - self.describe_field_from_ty(&tnm.ty, field) + ty::TyRef(_, ty, _) | ty::TyRawPtr(ty::TypeAndMut { ty, .. }) => { + self.describe_field_from_ty(&ty, field) } ty::TyArray(ty, _) | ty::TySlice(ty) => self.describe_field_from_ty(&ty, field), ty::TyClosure(def_id, _) | ty::TyGenerator(def_id, _, _) => { diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 3e3f510e308c3..1cc69351b4750 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() @@ -1906,8 +1913,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // Check the kind of deref to decide match base_ty.sty { - ty::TyRef(_, tnm) => { - match tnm.mutbl { + ty::TyRef(_, _, mutbl) => { + match mutbl { // Shared borrowed data is never mutable hir::MutImmutable => Err(place), // Mutably borrowed data is mutable, but only if we have a @@ -2341,13 +2348,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } ( ProjectionElem::Deref, - ty::TyRef( - _, - ty::TypeAndMut { - ty: _, - mutbl: hir::MutImmutable, - }, - ), + ty::TyRef( _, _, hir::MutImmutable), _, ) => { // the borrow goes through a dereference of a shared reference. diff --git a/src/librustc_mir/borrow_check/nll/constraint_generation.rs b/src/librustc_mir/borrow_check/nll/constraint_generation.rs index d34e9434fbf2a..4f87a2b30ae84 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) { @@ -263,7 +270,7 @@ impl<'cx, 'cg, 'gcx, 'tcx> ConstraintGeneration<'cx, 'cg, 'gcx, 'tcx> { debug!("add_reborrow_constraint - base_ty = {:?}", base_ty); match base_ty.sty { - ty::TyRef(ref_region, ty::TypeAndMut { ty: _, mutbl }) => { + ty::TyRef(ref_region, _, mutbl) => { let span = self.mir.source_info(location).span; self.regioncx.add_outlives( span, 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..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/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs index 0fe6265345de1..52ebf38c668c2 100644 --- a/src/librustc_mir/borrow_check/nll/universal_regions.rs +++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs @@ -22,13 +22,13 @@ //! 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; 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,7 +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>), + 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. @@ -509,7 +509,7 @@ 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)) + Some(substs.yield_ty(def_id, self.infcx.tcx)) } _ => None, }; @@ -550,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) => { - DefiningTy::Generator(def_id, substs, interior) + ty::TyGenerator(def_id, substs, movability) => { + DefiningTy::Generator(def_id, substs, movability) } ty::TyFnDef(def_id, substs) => DefiningTy::FnDef(def_id, substs), _ => span_bug!( @@ -587,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`. @@ -595,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, @@ -648,10 +649,10 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> { ) } - DefiningTy::Generator(def_id, substs, interior) => { + 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); + 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/borrow_check/prefixes.rs b/src/librustc_mir/borrow_check/prefixes.rs index 645c935de09b1..dee78341265bf 100644 --- a/src/librustc_mir/borrow_check/prefixes.rs +++ b/src/librustc_mir/borrow_check/prefixes.rs @@ -156,10 +156,8 @@ impl<'cx, 'gcx, 'tcx> Iterator for Prefixes<'cx, 'gcx, 'tcx> { ty::TyRawPtr(_) | ty::TyRef( _, /*rgn*/ - ty::TypeAndMut { - ty: _, - mutbl: hir::MutImmutable, - }, + _, /*ty*/ + hir::MutImmutable ) => { // don't continue traversing over derefs of raw pointers or shared borrows. self.next = None; @@ -168,10 +166,8 @@ impl<'cx, 'gcx, 'tcx> Iterator for Prefixes<'cx, 'gcx, 'tcx> { ty::TyRef( _, /*rgn*/ - ty::TypeAndMut { - ty: _, - mutbl: hir::MutMutable, - }, + _, /*ty*/ + hir::MutMutable, ) => { self.next = Some(&proj.base); return Some(cursor); diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 9e96fdf821417..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,27 +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 } => { // see (*) above + 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) = 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) - } 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/matches/test.rs b/src/librustc_mir/build/matches/test.rs index c50d84c10d86e..d6ddfea1f19fb 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -276,7 +276,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // array, so we can call `<[u8]>::eq` rather than having to find an // `<[u8; N]>::eq`. let unsize = |ty: Ty<'tcx>| match ty.sty { - ty::TyRef(region, tam) => match tam.ty.sty { + ty::TyRef(region, rty, _) => match rty.sty { ty::TyArray(inner_ty, n) => Some((region, inner_ty, n)), _ => None, }, 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 d0c352319c8c5..76605a7aa0484 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -283,7 +283,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, hir::ExprAddrOf(mutbl, ref expr) => { let region = match expr_ty.sty { - ty::TyRef(r, _) => r, + ty::TyRef(r, _, _) => r, _ => span_bug!(expr.span, "type of & not region"), }; ExprKind::Borrow { @@ -470,9 +470,11 @@ 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) => (def_id, substs, Some(interior)), + 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); } @@ -487,7 +489,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, closure_id: def_id, substs, upvars, - interior, + movability, } } @@ -985,13 +987,13 @@ fn overloaded_place<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // Reconstruct the output assuming it's a reference with the // same region and mutability as the receiver. This holds for // `Deref(Mut)::Deref(_mut)` and `Index(Mut)::index(_mut)`. - let (region, mt) = match recv_ty.sty { - ty::TyRef(region, mt) => (region, mt), + let (region, mutbl) = match recv_ty.sty { + ty::TyRef(region, _, mutbl) => (region, mutbl), _ => span_bug!(expr.span, "overloaded_place: receiver is not a reference"), }; let ref_ty = cx.tcx.mk_ref(region, ty::TypeAndMut { ty: place_ty, - mutbl: mt.mutbl, + mutbl, }); // construct the complete expression `foo()` for the overloaded call, diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index fe82b8158f76d..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>, + movability: Option, }, Literal { literal: Literal<'tcx>, diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index ff7b4f9e0fd70..1245f506955c1 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -46,13 +46,13 @@ struct LiteralExpander; impl<'tcx> PatternFolder<'tcx> for LiteralExpander { fn fold_pattern(&mut self, pat: &Pattern<'tcx>) -> Pattern<'tcx> { match (&pat.ty.sty, &*pat.kind) { - (&ty::TyRef(_, mt), &PatternKind::Constant { ref value }) => { + (&ty::TyRef(_, rty, _), &PatternKind::Constant { ref value }) => { Pattern { ty: pat.ty, span: pat.span, kind: box PatternKind::Deref { subpattern: Pattern { - ty: mt.ty, + ty: rty, span: pat.span, kind: box PatternKind::Constant { value: value.clone() }, } @@ -907,7 +907,7 @@ fn constructor_sub_pattern_tys<'a, 'tcx: 'a>(cx: &MatchCheckCtxt<'a, 'tcx>, ConstantValue(_) => vec![], _ => bug!("bad slice pattern {:?} {:?}", ctor, ty) }, - ty::TyRef(_, ref ty_and_mut) => vec![ty_and_mut.ty], + ty::TyRef(_, rty, _) => vec![rty], ty::TyAdt(adt, substs) => { if adt.is_box() { // Use T as the sub pattern type of Box. diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 623e0de478bca..2585447fa0a04 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -238,9 +238,9 @@ impl<'tcx> fmt::Display for Pattern<'tcx> { PatternKind::Deref { ref subpattern } => { match self.ty.sty { ty::TyAdt(def, _) if def.is_box() => write!(f, "box ")?, - ty::TyRef(_, mt) => { + ty::TyRef(_, _, mutbl) => { write!(f, "&")?; - if mt.mutbl == hir::MutMutable { + if mutbl == hir::MutMutable { write!(f, "mut ")?; } } @@ -424,13 +424,13 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { PatKind::Slice(ref prefix, ref slice, ref suffix) => { let ty = self.tables.node_id_to_type(pat.hir_id); match ty.sty { - ty::TyRef(_, mt) => + ty::TyRef(_, ty, _) => PatternKind::Deref { subpattern: Pattern { - ty: mt.ty, + ty, span: pat.span, kind: Box::new(self.slice_or_array_pattern( - pat.span, mt.ty, prefix, slice, suffix)) + pat.span, ty, prefix, slice, suffix)) }, }, @@ -469,7 +469,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { PatKind::Binding(_, id, ref name, ref sub) => { let var_ty = self.tables.node_id_to_type(pat.hir_id); let region = match var_ty.sty { - ty::TyRef(r, _) => Some(r), + ty::TyRef(r, _, _) => Some(r), _ => None, }; let bm = *self.tables.pat_binding_modes().get(pat.hir_id) @@ -490,8 +490,8 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { // A ref x pattern is the same node used for x, and as such it has // x's type, which is &T, where we want T (the type being matched). if let ty::BindByReference(_) = bm { - if let ty::TyRef(_, mt) = ty.sty { - ty = mt.ty; + if let ty::TyRef(_, rty, _) = ty.sty { + ty = rty; } else { bug!("`ref {}` has wrong type {}", name.node, ty); } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index f5fd14036c4d0..00cc91db8480c 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -7,7 +7,7 @@ use rustc::middle::const_val::{ConstVal, ErrKind}; use rustc::mir; use rustc::ty::layout::{self, Size, Align, HasDataLayout, IntegerExt, LayoutOf, TyLayout}; use rustc::ty::subst::{Subst, Substs}; -use rustc::ty::{self, Ty, TyCtxt}; +use rustc::ty::{self, Ty, TyCtxt, TypeAndMut}; use rustc::ty::maps::TyCtxtAt; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; use rustc::middle::const_val::FrameInfo; @@ -775,8 +775,8 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M pub(super) fn type_is_fat_ptr(&self, ty: Ty<'tcx>) -> bool { match ty.sty { - ty::TyRawPtr(ref tam) | - ty::TyRef(_, ref tam) => !self.type_is_sized(tam.ty), + ty::TyRawPtr(ty::TypeAndMut { ty, .. }) | + ty::TyRef(_, ty, _) => !self.type_is_sized(ty), ty::TyAdt(def, _) if def.is_box() => !self.type_is_sized(ty.boxed_ty()), _ => false, } @@ -1259,8 +1259,10 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M ty::TyFnPtr(_) => PrimValKind::FnPtr, - ty::TyRef(_, ref tam) | - ty::TyRawPtr(ref tam) if self.type_is_sized(tam.ty) => PrimValKind::Ptr, + ty::TyRef(_, ty, _) | + ty::TyRawPtr(ty::TypeAndMut { ty, .. }) if self.type_is_sized(ty) => { + PrimValKind::Ptr + } ty::TyAdt(def, _) if def.is_box() => PrimValKind::Ptr, @@ -1400,8 +1402,10 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M } ty::TyFnPtr(_) => self.memory.read_ptr_sized(ptr, ptr_align)?, - ty::TyRef(_, ref tam) | - ty::TyRawPtr(ref tam) => return self.read_ptr(ptr, ptr_align, tam.ty).map(Some), + ty::TyRef(_, rty, _) | + ty::TyRawPtr(ty::TypeAndMut { ty: rty, .. }) => { + return self.read_ptr(ptr, ptr_align, rty).map(Some) + } ty::TyAdt(def, _) => { if def.is_box() { @@ -1501,10 +1505,11 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M dst_layout: TyLayout<'tcx>, ) -> EvalResult<'tcx> { match (&src_layout.ty.sty, &dst_layout.ty.sty) { - (&ty::TyRef(_, ref s), &ty::TyRef(_, ref d)) | - (&ty::TyRef(_, ref s), &ty::TyRawPtr(ref d)) | - (&ty::TyRawPtr(ref s), &ty::TyRawPtr(ref d)) => { - self.unsize_into_ptr(src, src_layout.ty, dst, dst_layout.ty, s.ty, d.ty) + (&ty::TyRef(_, s, _), &ty::TyRef(_, d, _)) | + (&ty::TyRef(_, s, _), &ty::TyRawPtr(TypeAndMut { ty: d, .. })) | + (&ty::TyRawPtr(TypeAndMut { ty: s, .. }), + &ty::TyRawPtr(TypeAndMut { ty: d, .. })) => { + self.unsize_into_ptr(src, src_layout.ty, dst, dst_layout.ty, s, d) } (&ty::TyAdt(def_a, _), &ty::TyAdt(def_b, _)) => { assert_eq!(def_a, def_b); diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index d03204bfab16d..b5a06286e4eed 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -369,8 +369,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { let val = self.read_place(base)?; let pointee_type = match base_ty.sty { - ty::TyRawPtr(ref tam) | - ty::TyRef(_, ref tam) => tam.ty, + ty::TyRawPtr(ref tam) => tam.ty, + ty::TyRef(_, ty, _) => ty, ty::TyAdt(def, _) if def.is_box() => base_ty.boxed_ty(), _ => bug!("can only deref pointer types"), }; diff --git a/src/librustc_mir/interpret/terminator/mod.rs b/src/librustc_mir/interpret/terminator/mod.rs index 0e0d91f472472..c61487f106b66 100644 --- a/src/librustc_mir/interpret/terminator/mod.rs +++ b/src/librustc_mir/interpret/terminator/mod.rs @@ -199,7 +199,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { // mutability of raw pointers. // TODO: Should not be allowed when fat pointers are involved. (&ty::TyRawPtr(_), &ty::TyRawPtr(_)) => true, - (&ty::TyRef(_, _), &ty::TyRef(_, _)) => { + (&ty::TyRef(_, _, _), &ty::TyRef(_, _, _)) => { ty.is_mutable_pointer() == real_ty.is_mutable_pointer() } // rule out everything else diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 610e70b39ccf9..e051b848c011f 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -844,9 +844,9 @@ fn find_vtable_types_for_unsizing<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }; match (&source_ty.sty, &target_ty.sty) { - (&ty::TyRef(_, ty::TypeAndMut { ty: a, .. }), - &ty::TyRef(_, ty::TypeAndMut { ty: b, .. })) | - (&ty::TyRef(_, ty::TypeAndMut { ty: a, .. }), + (&ty::TyRef(_, a, _), + &ty::TyRef(_, b, _)) | + (&ty::TyRef(_, a, _), &ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) | (&ty::TyRawPtr(ty::TypeAndMut { ty: a, .. }), &ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) => { diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 9e43bed1b63af..176ed8c5bca74 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; @@ -302,7 +302,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { self.push_type_name(inner_type, output); }, - ty::TyRef(_, ty::TypeAndMut { ty: inner_type, mutbl }) => { + ty::TyRef(_, inner_type, mutbl) => { output.push('&'); if mutbl == hir::MutMutable { output.push_str("mut "); @@ -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/transform/add_validation.rs b/src/librustc_mir/transform/add_validation.rs index f0f6add3f6f81..584887d03738f 100644 --- a/src/librustc_mir/transform/add_validation.rs +++ b/src/librustc_mir/transform/add_validation.rs @@ -44,14 +44,14 @@ fn place_context<'a, 'tcx, D>( // A Deref projection may restrict the context, this depends on the type // being deref'd. let context = match ty.sty { - ty::TyRef(re, tam) => { + ty::TyRef(re, _, mutbl) => { let re = match re { &RegionKind::ReScope(ce) => Some(ce), &RegionKind::ReErased => bug!("AddValidation pass must be run before erasing lifetimes"), _ => None }; - (re, tam.mutbl) + (re, mutbl) } ty::TyRawPtr(_) => // There is no guarantee behind even a mutable raw pointer, 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 36735586e8117..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,8 @@ 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)>, GeneratorLayout<'tcx>, @@ -474,11 +475,11 @@ 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); - let allowed = match interior.witness.sty { + let allowed = match interior.sty { ty::TyGeneratorWitness(s) => tcx.erase_late_bound_regions(&s), _ => bug!(), }; @@ -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, movability) => { + (substs.upvar_tys(def_id, tcx).collect(), + substs.witness(def_id, tcx), + 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..a641cf3d93ecf 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -780,7 +780,10 @@ 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. diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index a891e372ad8b5..71012ca6d5f79 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -418,11 +418,11 @@ 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, 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..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) => { + 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/base.rs b/src/librustc_trans/base.rs index b756a6695f941..33dc9b3b7ab90 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -228,9 +228,9 @@ pub fn unsize_thin_ptr<'a, 'tcx>( ) -> (ValueRef, ValueRef) { debug!("unsize_thin_ptr: {:?} => {:?}", src_ty, dst_ty); match (&src_ty.sty, &dst_ty.sty) { - (&ty::TyRef(_, ty::TypeAndMut { ty: a, .. }), - &ty::TyRef(_, ty::TypeAndMut { ty: b, .. })) | - (&ty::TyRef(_, ty::TypeAndMut { ty: a, .. }), + (&ty::TyRef(_, a, _), + &ty::TyRef(_, b, _)) | + (&ty::TyRef(_, a, _), &ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) | (&ty::TyRawPtr(ty::TypeAndMut { ty: a, .. }), &ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) => { diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 4a0619b23360d..75b56be3c162a 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -423,7 +423,7 @@ pub fn ty_fn_sig<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } 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 f16fef5ec1e84..ae23b523cbfae 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -555,7 +555,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, false) } ty::TyRawPtr(ty::TypeAndMut{ty, ..}) | - ty::TyRef(_, ty::TypeAndMut{ty, ..}) => { + ty::TyRef(_, ty, _) => { match ptr_metadata(ty) { Ok(res) => res, Err(metadata) => return metadata, @@ -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/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs index 825fac36c93d7..565a9bedef0f5 100644 --- a/src/librustc_trans/debuginfo/type_names.rs +++ b/src/librustc_trans/debuginfo/type_names.rs @@ -80,7 +80,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, output.push('*'); } }, - ty::TyRef(_, ty::TypeAndMut { ty: inner_type, mutbl }) => { + ty::TyRef(_, inner_type, mutbl) => { if !cpp_like_names { output.push('&'); } diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs index a074f25dfc9ba..8ea0983075dc4 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; @@ -571,15 +571,17 @@ fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>, // Or is it the closure environment? let (closure_layout, env_ref) = match arg.layout.ty.sty { - ty::TyRef(_, mt) | ty::TyRawPtr(mt) => (bx.cx.layout_of(mt.ty), true), + ty::TyRawPtr(ty::TypeAndMut { ty, .. }) | + ty::TyRef(_, ty, _) => (bx.cx.layout_of(ty), true), _ => (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. @@ -614,8 +616,8 @@ fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>, // a pointer in an alloca for debuginfo atm. let mut ops = if env_ref || true { &ops[..] } else { &ops[1..] }; - let ty = if let (true, &ty::TyRef(_, mt)) = (decl.by_ref, &ty.sty) { - mt.ty + let ty = if let (true, &ty::TyRef(_, ty, _)) = (decl.by_ref, &ty.sty) { + ty } else { ops = &ops[..ops.len() - 1]; ty diff --git a/src/librustc_trans/type_of.rs b/src/librustc_trans/type_of.rs index 5e6b276495764..f736e81202a38 100644 --- a/src/librustc_trans/type_of.rs +++ b/src/librustc_trans/type_of.rs @@ -250,7 +250,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { return llty; } let llty = match self.ty.sty { - ty::TyRef(_, ty::TypeAndMut { ty, .. }) | + ty::TyRef(_, ty, _) | ty::TyRawPtr(ty::TypeAndMut { ty, .. }) => { cx.layout_of(ty).llvm_type(cx).ptr_to() } @@ -418,11 +418,11 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { }); } - ty::TyRef(_, mt) if offset.bytes() == 0 => { - let (size, align) = cx.size_and_align_of(mt.ty); + ty::TyRef(_, ty, mt) if offset.bytes() == 0 => { + let (size, align) = cx.size_and_align_of(ty); - let kind = match mt.mutbl { - hir::MutImmutable => if cx.type_is_freeze(mt.ty) { + let kind = match mt { + hir::MutImmutable => if cx.type_is_freeze(ty) { PointerKind::Frozen } else { PointerKind::Shared diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 7b4dc60409b12..c7585c827ce11 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -84,9 +84,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expected = loop { debug!("inspecting {:?} with type {:?}", exp_ty, exp_ty.sty); match exp_ty.sty { - ty::TypeVariants::TyRef(_, ty::TypeAndMut{ - ty: inner_ty, mutbl: inner_mutability, - }) => { + ty::TypeVariants::TyRef(_, inner_ty, inner_mutability) => { debug!("current discriminant is TyRef, inserting implicit deref"); // Preserve the reference type. We'll need it later during HAIR lowering. pat_adjustments.push(exp_ty); @@ -152,8 +150,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let hir::ExprLit(ref lt) = lt.node { if let ast::LitKind::ByteStr(_) = lt.node { let expected_ty = self.structurally_resolved_type(pat.span, expected); - if let ty::TyRef(_, mt) = expected_ty.sty { - if let ty::TySlice(_) = mt.ty.sty { + if let ty::TyRef(_, r_ty, _) = expected_ty.sty { + if let ty::TySlice(_) = r_ty.sty { pat_ty = tcx.mk_imm_ref(tcx.types.re_static, tcx.mk_slice(tcx.types.u8)) } @@ -334,8 +332,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // hack detailed in (*) below. debug!("check_pat_walk: expected={:?}", expected); let (rptr_ty, inner_ty) = match expected.sty { - ty::TyRef(_, mt) if mt.mutbl == mutbl => { - (expected, mt.ty) + ty::TyRef(_, r_ty, r_mutbl) if r_mutbl == mutbl => { + (expected, r_ty) } _ => { let inner_ty = self.next_ty_var( @@ -408,7 +406,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { tcx.sess, pat.span, E0529, "expected an array or slice, found `{}`", expected_ty); - if let ty::TyRef(_, ty::TypeAndMut { mutbl: _, ty }) = expected_ty.sty { + if let ty::TyRef(_, ty, _) = expected_ty.sty { match ty.sty { ty::TyArray(..) | ty::TySlice(..) => { err.help("the semantics of slice patterns changed \ diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs index 3199ff17ae926..e1ce6073ce436 100644 --- a/src/librustc_typeck/check/autoderef.rs +++ b/src/librustc_typeck/check/autoderef.rs @@ -177,10 +177,10 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> { self.fcx.try_overloaded_deref(self.span, source, needs) .and_then(|InferOk { value: method, obligations: o }| { obligations.extend(o); - if let ty::TyRef(region, mt) = method.sig.output().sty { + if let ty::TyRef(region, _, mutbl) = method.sig.output().sty { Some(OverloadedDeref { region, - mutbl: mt.mutbl, + mutbl, }) } else { None diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 4df496763e40a..b0f9a4c8b85ad 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -175,8 +175,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let method = self.register_infer_ok_obligations(ok); let mut autoref = None; if borrow { - if let ty::TyRef(region, mt) = method.sig.inputs()[0].sty { - let mutbl = match mt.mutbl { + if let ty::TyRef(region, _, mutbl) = method.sig.inputs()[0].sty { + let mutbl = match mutbl { hir::MutImmutable => AutoBorrowMutability::Immutable, hir::MutMutable => AutoBorrowMutability::Mutable { // For initial two-phase borrow diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 734d72584da9b..f0d7ca8ebf14f 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -46,7 +46,7 @@ use lint; use rustc::hir; use rustc::session::Session; use rustc::traits; -use rustc::ty::{self, Ty, TypeFoldable}; +use rustc::ty::{self, Ty, TypeFoldable, TypeAndMut}; use rustc::ty::adjustment::AllowTwoPhase; use rustc::ty::cast::{CastKind, CastTy}; use rustc::ty::subst::Substs; @@ -319,7 +319,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { fcx.resolve_type_vars_if_possible(&self.expr_ty), tstr); match self.expr_ty.sty { - ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => { + ty::TyRef(_, _, mt) => { let mtstr = match mt { hir::MutMutable => "mut ", hir::MutImmutable => "", @@ -511,8 +511,8 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { fn check_ptr_ptr_cast(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, - m_expr: &'tcx ty::TypeAndMut<'tcx>, - m_cast: &'tcx ty::TypeAndMut<'tcx>) + m_expr: ty::TypeAndMut<'tcx>, + m_cast: ty::TypeAndMut<'tcx>) -> Result { debug!("check_ptr_ptr_cast m_expr={:?} m_cast={:?}", m_expr, m_cast); // ptr-ptr cast. vtables must match. @@ -552,7 +552,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { fn check_fptr_ptr_cast(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, - m_cast: &'tcx ty::TypeAndMut<'tcx>) + m_cast: ty::TypeAndMut<'tcx>) -> Result { // fptr-ptr cast. must be to thin ptr @@ -565,7 +565,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { fn check_ptr_addr_cast(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, - m_expr: &'tcx ty::TypeAndMut<'tcx>) + m_expr: ty::TypeAndMut<'tcx>) -> Result { // ptr-addr cast. must be from thin ptr @@ -578,8 +578,8 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { fn check_ref_cast(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, - m_expr: &'tcx ty::TypeAndMut<'tcx>, - m_cast: &'tcx ty::TypeAndMut<'tcx>) + m_expr: ty::TypeAndMut<'tcx>, + m_cast: ty::TypeAndMut<'tcx>) -> Result { // array-ptr-cast. @@ -603,7 +603,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { fn check_addr_ptr_cast(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, - m_cast: &'tcx ty::TypeAndMut<'tcx>) + m_cast: TypeAndMut<'tcx>) -> Result { // ptr-addr cast. pointer must be thin. match fcx.pointer_kind(m_cast.ty, self.span)? { diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 3b9d561ffc5a5..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 }) = generator_types { + 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); + 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/coercion.rs b/src/librustc_typeck/check/coercion.rs index 8c69608a26170..c1ef916e27db3 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -214,7 +214,8 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { return self.coerce_unsafe_ptr(a, b, mt_b.mutbl); } - ty::TyRef(r_b, mt_b) => { + ty::TyRef(r_b, ty, mutbl) => { + let mt_b = ty::TypeAndMut { ty, mutbl }; return self.coerce_borrowed_pointer(a, b, r_b, mt_b); } @@ -266,7 +267,8 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { // yield. let (r_a, mt_a) = match a.sty { - ty::TyRef(r_a, mt_a) => { + ty::TyRef(r_a, ty, mutbl) => { + let mt_a = ty::TypeAndMut { ty, mutbl }; coerce_mutbls(mt_a.mutbl, mt_b.mutbl)?; (r_a, mt_a) } @@ -427,7 +429,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { // Now apply the autoref. We have to extract the region out of // the final ref type we got. let r_borrow = match ty.sty { - ty::TyRef(r_borrow, _) => r_borrow, + ty::TyRef(r_borrow, _, _) => r_borrow, _ => span_bug!(span, "expected a ref type, got {:?}", ty), }; let mutbl = match mt_b.mutbl { @@ -471,12 +473,12 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { // Handle reborrows before selecting `Source: CoerceUnsized`. let reborrow = match (&source.sty, &target.sty) { - (&ty::TyRef(_, mt_a), &ty::TyRef(_, mt_b)) => { - coerce_mutbls(mt_a.mutbl, mt_b.mutbl)?; + (&ty::TyRef(_, ty_a, mutbl_a), &ty::TyRef(_, _, mutbl_b)) => { + coerce_mutbls(mutbl_a, mutbl_b)?; let coercion = Coercion(self.cause.span); let r_borrow = self.next_region_var(coercion); - let mutbl = match mt_b.mutbl { + let mutbl = match mutbl_b { hir::MutImmutable => AutoBorrowMutability::Immutable, hir::MutMutable => AutoBorrowMutability::Mutable { // We don't allow two-phase borrows here, at least for initial @@ -487,26 +489,26 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { }; Some((Adjustment { kind: Adjust::Deref(None), - target: mt_a.ty + target: ty_a }, Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(r_borrow, mutbl)), target: self.tcx.mk_ref(r_borrow, ty::TypeAndMut { - mutbl: mt_b.mutbl, - ty: mt_a.ty + mutbl: mutbl_b, + ty: ty_a }) })) } - (&ty::TyRef(_, mt_a), &ty::TyRawPtr(mt_b)) => { - coerce_mutbls(mt_a.mutbl, mt_b.mutbl)?; + (&ty::TyRef(_, ty_a, mt_a), &ty::TyRawPtr(ty::TypeAndMut { mutbl: mt_b, .. })) => { + coerce_mutbls(mt_a, mt_b)?; Some((Adjustment { kind: Adjust::Deref(None), - target: mt_a.ty + target: ty_a }, Adjustment { - kind: Adjust::Borrow(AutoBorrow::RawPtr(mt_b.mutbl)), + kind: Adjust::Borrow(AutoBorrow::RawPtr(mt_b)), target: self.tcx.mk_ptr(ty::TypeAndMut { - mutbl: mt_b.mutbl, - ty: mt_a.ty + mutbl: mt_b, + ty: ty_a }) })) } @@ -719,7 +721,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { debug!("coerce_unsafe_ptr(a={:?}, b={:?})", a, b); let (is_ref, mt_a) = match a.sty { - ty::TyRef(_, mt) => (true, mt), + ty::TyRef(_, ty, mutbl) => (true, ty::TypeAndMut { ty, mutbl }), ty::TyRawPtr(mt) => (false, mt), _ => { return self.unify_and(a, b, identity); @@ -886,12 +888,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl_adj)), .. } ] => { match self.node_ty(expr.hir_id).sty { - ty::TyRef(_, mt_orig) => { + ty::TyRef(_, _, mt_orig) => { let mutbl_adj: hir::Mutability = mutbl_adj.into(); // Reborrow that we can safely ignore, because // the next adjustment can only be a Deref // which will be merged into it. - mutbl_adj == mt_orig.mutbl + mutbl_adj == mt_orig } _ => false, } diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index c0d6993c7d4dd..06d854c15fe5b 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -216,7 +216,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expected: Ty<'tcx>) -> Option<(&'static str, String)> { match (&expected.sty, &checked_ty.sty) { - (&ty::TyRef(_, exp), &ty::TyRef(_, check)) => match (&exp.ty.sty, &check.ty.sty) { + (&ty::TyRef(_, exp, _), &ty::TyRef(_, check, _)) => match (&exp.sty, &check.sty) { (&ty::TyStr, &ty::TyArray(arr, _)) | (&ty::TyStr, &ty::TySlice(arr)) if arr == self.tcx.types.u8 => { if let hir::ExprLit(_) = expr.node { @@ -241,7 +241,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } _ => None, }, - (&ty::TyRef(_, mutability), _) => { + (&ty::TyRef(_, _, mutability), _) => { // Check if it can work when put into a ref. For example: // // ``` @@ -250,7 +250,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // let x = 0u32; // bar(&x); // error, expected &mut // ``` - let ref_ty = match mutability.mutbl { + let ref_ty = match mutability { hir::Mutability::MutMutable => self.tcx.mk_mut_ref( self.tcx.mk_region(ty::ReStatic), checked_ty), @@ -266,7 +266,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { hir::ExprCast(_, _) | hir::ExprBinary(_, _, _) => format!("({})", src), _ => src, }; - return Some(match mutability.mutbl { + return Some(match mutability { hir::Mutability::MutMutable => { ("consider mutably borrowing here", format!("&mut {}", sugg_expr)) } @@ -278,7 +278,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } None } - (_, &ty::TyRef(_, checked)) => { + (_, &ty::TyRef(_, checked, _)) => { // We have `&T`, check if what was expected was `T`. If so, // we may want to suggest adding a `*`, or removing // a `&`. @@ -286,7 +286,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // (But, also check check the `expn_info()` to see if this is // a macro; if so, it's hard to extract the text and make a good // suggestion, so don't bother.) - if self.infcx.can_sub(self.param_env, checked.ty, &expected).is_ok() && + if self.infcx.can_sub(self.param_env, checked, &expected).is_ok() && expr.span.ctxt().outer().expn_info().is_none() { match expr.node { // Maybe remove `&`? @@ -299,7 +299,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Maybe add `*`? Only if `T: Copy`. _ => { if !self.infcx.type_moves_by_default(self.param_env, - checked.ty, + checked, expr.span) { let sp = self.sess().codemap().call_span_if_macro(expr.span); if let Ok(code) = self.tcx.sess.codemap().span_to_snippet(sp) { 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/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 09feaaffc5b9d..46288181037f4 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -462,10 +462,10 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { if let Adjust::Deref(Some(ref mut deref)) = adjustment.kind { if let Some(ok) = self.try_overloaded_deref(expr.span, source, needs) { let method = self.register_infer_ok_obligations(ok); - if let ty::TyRef(region, mt) = method.sig.output().sty { + if let ty::TyRef(region, _, mutbl) = method.sig.output().sty { *deref = OverloadedDeref { region, - mutbl: mt.mutbl + mutbl, }; } } @@ -521,8 +521,8 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { debug!("convert_place_op_to_mutable: method={:?}", method); self.write_method_call(expr.hir_id, method); - let (region, mutbl) = if let ty::TyRef(r, mt) = method.sig.inputs()[0].sty { - (r, mt.mutbl) + let (region, mutbl) = if let ty::TyRef(r, _, mutbl) = method.sig.inputs()[0].sty { + (r, mutbl) } else { span_bug!(expr.span, "input to place op is not a ref?"); }; diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 907c80f0daf5e..e45565c2f5220 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -917,9 +917,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { pick.autoderefs = step.autoderefs; // Insert a `&*` or `&mut *` if this is a reference type: - if let ty::TyRef(_, mt) = step.self_ty.sty { + if let ty::TyRef(_, _, mutbl) = step.self_ty.sty { pick.autoderefs += 1; - pick.autoref = Some(mt.mutbl); + pick.autoref = Some(mutbl); } pick diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index db859e42057e9..ef14fa9a12248 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,10 @@ 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, } /// Helper used for fns and closures. Does the grungy work of checking a function @@ -1084,13 +1087,13 @@ 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, - movable: can_be_generator.unwrap() == hir::GeneratorMovability::Movable, - }; + 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 }) + Some(GeneratorTypes { + yield_ty: fcx.yield_ty.unwrap(), + interior, + movability: can_be_generator.unwrap(), + }) } else { None }; @@ -2390,8 +2393,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let method = self.register_infer_ok_obligations(ok); let mut adjustments = autoderef.adjust_steps(needs); - if let ty::TyRef(region, mt) = method.sig.inputs()[0].sty { - let mutbl = match mt.mutbl { + if let ty::TyRef(region, _, r_mutbl) = method.sig.inputs()[0].sty { + let mutbl = match r_mutbl { hir::MutImmutable => AutoBorrowMutability::Immutable, hir::MutMutable => AutoBorrowMutability::Mutable { // Indexing can be desugared to a method call, @@ -2404,7 +2407,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { adjustments.push(Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)), target: self.tcx.mk_ref(region, ty::TypeAndMut { - mutbl: mt.mutbl, + mutbl: r_mutbl, ty: adjusted_ty }) }); @@ -3612,8 +3615,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } else if let Some(ok) = self.try_overloaded_deref( expr.span, oprnd_t, needs) { let method = self.register_infer_ok_obligations(ok); - if let ty::TyRef(region, mt) = method.sig.inputs()[0].sty { - let mutbl = match mt.mutbl { + if let ty::TyRef(region, _, mutbl) = method.sig.inputs()[0].sty { + let mutbl = match mutbl { hir::MutImmutable => AutoBorrowMutability::Immutable, hir::MutMutable => AutoBorrowMutability::Mutable { // (It shouldn't actually matter for unary ops whether @@ -3657,14 +3660,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { hir::ExprAddrOf(mutbl, ref oprnd) => { let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| { match ty.sty { - ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => { + ty::TyRef(_, ty, _) | ty::TyRawPtr(ty::TypeAndMut { ty, .. }) => { if self.is_place_expr(&oprnd) { // Places may legitimately have unsized types. // For example, dereferences of a fat pointer and // the last field of a struct can be unsized. - ExpectHasType(mt.ty) + ExpectHasType(ty) } else { - Expectation::rvalue_hint(self, mt.ty) + Expectation::rvalue_hint(self, ty) } } _ => NoExpectation diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index 4a175248d74a3..9e8e00594e60a 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -197,8 +197,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Ok(method) => { let by_ref_binop = !op.node.is_by_value(); if is_assign == IsAssign::Yes || by_ref_binop { - if let ty::TyRef(region, mt) = method.sig.inputs()[0].sty { - let mutbl = match mt.mutbl { + if let ty::TyRef(region, _, mutbl) = method.sig.inputs()[0].sty { + let mutbl = match mutbl { hir::MutImmutable => AutoBorrowMutability::Immutable, hir::MutMutable => AutoBorrowMutability::Mutable { // Allow two-phase borrows for binops in initial deployment @@ -214,8 +214,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } if by_ref_binop { - if let ty::TyRef(region, mt) = method.sig.inputs()[1].sty { - let mutbl = match mt.mutbl { + if let ty::TyRef(region, _, mutbl) = method.sig.inputs()[1].sty { + let mutbl = match mutbl { hir::MutImmutable => AutoBorrowMutability::Immutable, hir::MutMutable => AutoBorrowMutability::Mutable { // Allow two-phase borrows for binops in initial deployment @@ -262,12 +262,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { op.node.as_str(), lhs_ty); - if let TypeVariants::TyRef(_, ref ty_mut) = lhs_ty.sty { + if let TypeVariants::TyRef(_, rty, _) = lhs_ty.sty { if { !self.infcx.type_moves_by_default(self.param_env, - ty_mut.ty, + rty, lhs_expr.span) && - self.lookup_op_method(ty_mut.ty, + self.lookup_op_method(rty, &[rhs_ty], Op::Binary(op, is_assign)) .is_ok() @@ -341,8 +341,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // If this function returns true it means a note was printed, so we don't need // to print the normal "implementation of `std::ops::Add` might be missing" note match (&lhs_ty.sty, &rhs_ty.sty) { - (&TyRef(_, ref l_ty), &TyRef(_, ref r_ty)) - if l_ty.ty.sty == TyStr && r_ty.ty.sty == TyStr => { + (&TyRef(_, l_ty, _), &TyRef(_, r_ty, _)) + if l_ty.sty == TyStr && r_ty.sty == TyStr => { err.span_label(expr.span, "`+` can't be used to concatenate two `&str` strings"); match codemap.span_to_snippet(lhs_expr.span) { @@ -353,8 +353,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; true } - (&TyRef(_, ref l_ty), &TyAdt(..)) - if l_ty.ty.sty == TyStr && &format!("{:?}", rhs_ty) == "std::string::String" => { + (&TyRef(_, l_ty, _), &TyAdt(..)) + if l_ty.sty == TyStr && &format!("{:?}", rhs_ty) == "std::string::String" => { err.span_label(expr.span, "`+` can't be used to concatenate a `&str` with a `String`"); match codemap.span_to_snippet(lhs_expr.span) { diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index e7e70a19e496b..badf5bcb6a9a0 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -588,7 +588,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { // For overloaded derefs, base_ty is the input to `Deref::deref`, // but it's a reference type uing the same region as the output. let base_ty = self.resolve_expr_type_adjusted(base); - if let ty::TyRef(r_ptr, _) = base_ty.sty { + if let ty::TyRef(r_ptr, _, _) = base_ty.sty { self.mk_subregion_due_to_dereference(expr.span, expr_region, r_ptr); } @@ -701,11 +701,11 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { from_ty, to_ty); match (&from_ty.sty, &to_ty.sty) { - /*From:*/ (&ty::TyRef(from_r, ref from_mt), - /*To: */ &ty::TyRef(to_r, ref to_mt)) => { + /*From:*/ (&ty::TyRef(from_r, from_ty, _), + /*To: */ &ty::TyRef(to_r, to_ty, _)) => { // Target cannot outlive source, naturally. self.sub_regions(infer::Reborrow(cast_expr.span), to_r, from_r); - self.walk_cast(cast_expr, from_mt.ty, to_mt.ty); + self.walk_cast(cast_expr, from_ty, to_ty); } /*From:*/ (_, @@ -913,8 +913,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { self.ty_to_string(indexed_ty)); let r_index_expr = ty::ReScope(region::Scope::Node(index_expr.hir_id.local_id)); - if let ty::TyRef(r_ptr, mt) = indexed_ty.sty { - match mt.ty.sty { + if let ty::TyRef(r_ptr, r_ty, _) = indexed_ty.sty { + match r_ty.sty { ty::TySlice(_) | ty::TyStr => { self.sub_regions(infer::IndexSlice(index_expr.span), self.tcx.mk_region(r_index_expr), r_ptr); @@ -1086,7 +1086,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { id, mutbl, cmt_borrowed); let rptr_ty = self.resolve_node_type(id); - if let ty::TyRef(r, _) = rptr_ty.sty { + if let ty::TyRef(r, _, _) = rptr_ty.sty { debug!("rptr_ty={}", rptr_ty); self.link_region(span, r, ty::BorrowKind::from_mutbl(mutbl), cmt_borrowed); } diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 58dc5839578f7..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,8 +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, @@ -121,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| { @@ -172,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; @@ -208,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/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 802e5375b6b28..57c1d33cb5d2a 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -172,7 +172,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { match tables.expr_ty_adjusted(&base).sty { // All valid indexing looks like this - ty::TyRef(_, ty::TypeAndMut { ty: ref base_ty, .. }) => { + ty::TyRef(_, base_ty, _) => { let index_ty = tables.expr_ty_adjusted(&index); let index_ty = self.fcx.resolve_type_vars_if_possible(&index_ty); diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index aa4322783c606..3424a31e09df0 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -223,12 +223,18 @@ pub fn coerce_unsized_info<'a, 'gcx>(gcx: TyCtxt<'a, 'gcx, 'gcx>, (mt_a.ty, mt_b.ty, unsize_trait, None) }; let (source, target, trait_def_id, kind) = match (&source.sty, &target.sty) { - (&ty::TyRef(r_a, mt_a), &ty::TyRef(r_b, mt_b)) => { + (&ty::TyRef(r_a, ty_a, mutbl_a), &ty::TyRef(r_b, ty_b, mutbl_b)) => { infcx.sub_regions(infer::RelateObjectBound(span), r_b, r_a); + let mt_a = ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a }; + let mt_b = ty::TypeAndMut { ty: ty_b, mutbl: mutbl_b }; check_mutbl(mt_a, mt_b, &|ty| gcx.mk_imm_ref(r_b, ty)) } - (&ty::TyRef(_, mt_a), &ty::TyRawPtr(mt_b)) | + (&ty::TyRef(_, ty_a, mutbl_a), &ty::TyRawPtr(mt_b)) => { + let mt_a = ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a }; + check_mutbl(mt_a, mt_b, &|ty| gcx.mk_imm_ptr(ty)) + } + (&ty::TyRawPtr(mt_a), &ty::TyRawPtr(mt_b)) => { check_mutbl(mt_a, mt_b, &|ty| gcx.mk_imm_ptr(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, + } })); }); } diff --git a/src/librustc_typeck/outlives/implicit_infer.rs b/src/librustc_typeck/outlives/implicit_infer.rs index 26fba71c81285..5a9539a8badf0 100644 --- a/src/librustc_typeck/outlives/implicit_infer.rs +++ b/src/librustc_typeck/outlives/implicit_infer.rs @@ -149,8 +149,8 @@ fn insert_required_predicates_to_be_wf<'tcx>( // a predicate requirement of T: 'a (T outlives 'a). // // We also want to calculate potential predicates for the T - ty::TyRef(region, mt) => { - insert_outlives_predicate(tcx, mt.ty.into(), region, required_predicates); + ty::TyRef(region, rty, _) => { + insert_outlives_predicate(tcx, rty.into(), region, required_predicates); } // For each TyAdt (struct/enum/union) type `Foo<'a, T>`, we diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index b5e7effa61e8d..ad7a3051f6402 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -272,10 +272,10 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { bug!("Unexpected closure type in variance computation"); } - ty::TyRef(region, ref mt) => { + ty::TyRef(region, ty, mutbl) => { let contra = self.contravariant(variance); self.add_constraints_from_region(current, region, contra); - self.add_constraints_from_mt(current, mt, variance); + self.add_constraints_from_mt(current, &ty::TypeAndMut { ty, mutbl }, variance); } ty::TyArray(typ, _) | diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index fb0bd0e42c57e..f27a3525d55bd 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1484,7 +1484,7 @@ impl<'a, 'tcx> Clean for (&'a ty::TraitRef<'tcx>, Vec for ty_s in trait_ref.input_types().skip(1) { if let ty::TyTuple(ts) = ty_s.sty { for &ty_s in ts { - if let ty::TyRef(ref reg, _) = ty_s.sty { + if let ty::TyRef(ref reg, _, _) = ty_s.sty { if let &ty::RegionKind::ReLateBound(..) = *reg { debug!(" hit an ReLateBound {:?}", reg); if let Some(lt) = reg.clean(cx) { @@ -2235,8 +2235,8 @@ impl<'tcx> Clean for ty::AssociatedItem { let self_arg_ty = *sig.input(0).skip_binder(); if self_arg_ty == self_ty { decl.inputs.values[0].type_ = Generic(String::from("Self")); - } else if let ty::TyRef(_, mt) = self_arg_ty.sty { - if mt.ty == self_ty { + } else if let ty::TyRef(_, ty, _) = self_arg_ty.sty { + if ty == self_ty { match decl.inputs.values[0].type_ { BorrowedRef{ref mut type_, ..} => { **type_ = Generic(String::from("Self")) @@ -2790,10 +2790,10 @@ impl<'tcx> Clean for Ty<'tcx> { Array(box ty.clean(cx), n) } ty::TyRawPtr(mt) => RawPointer(mt.mutbl.clean(cx), box mt.ty.clean(cx)), - ty::TyRef(r, mt) => BorrowedRef { + ty::TyRef(r, ty, mutbl) => BorrowedRef { lifetime: r.clean(cx), - mutability: mt.mutbl.clean(cx), - type_: box mt.ty.clean(cx), + mutability: mutbl.clean(cx), + type_: box ty.clean(cx), }, ty::TyFnDef(..) | ty::TyFnPtr(_) => {