diff options
Diffstat (limited to 'src')
30 files changed, 256 insertions, 159 deletions
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 77b5306c36e..c77e96f1648 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -143,10 +143,10 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) { enc_substs(w, cx, substs); mywrite!(w, "]"); } - ty::TyClosure(def, substs, ref tys) => { + ty::TyClosure(def, ref substs) => { mywrite!(w, "k[{}|", (cx.ds)(def)); - enc_substs(w, cx, substs); - for ty in tys { + enc_substs(w, cx, &substs.func_substs); + for ty in &substs.upvar_tys { enc_ty(w, cx, ty); } mywrite!(w, "."); diff --git a/src/librustc/middle/fast_reject.rs b/src/librustc/middle/fast_reject.rs index 4635e406c41..de7582a1371 100644 --- a/src/librustc/middle/fast_reject.rs +++ b/src/librustc/middle/fast_reject.rs @@ -76,7 +76,7 @@ pub fn simplify_type(tcx: &ty::ctxt, Err(msg) => tcx.sess.fatal(&msg), } } - ty::TyClosure(def_id, _, _) => { + ty::TyClosure(def_id, _) => { Some(ClosureSimplifiedType(def_id)) } ty::TyTuple(ref tys) => { diff --git a/src/librustc/middle/implicator.rs b/src/librustc/middle/implicator.rs index b6a8037fe03..8fba98bead4 100644 --- a/src/librustc/middle/implicator.rs +++ b/src/librustc/middle/implicator.rs @@ -28,7 +28,7 @@ use util::nodemap::FnvHashSet; pub enum Implication<'tcx> { RegionSubRegion(Option<Ty<'tcx>>, ty::Region, ty::Region), RegionSubGeneric(Option<Ty<'tcx>>, ty::Region, GenericKind<'tcx>), - RegionSubClosure(Option<Ty<'tcx>>, ty::Region, ast::DefId, &'tcx Substs<'tcx>), + RegionSubClosure(Option<Ty<'tcx>>, ty::Region, ast::DefId, &'tcx ty::ClosureSubsts<'tcx>), Predicate(ast::DefId, ty::Predicate<'tcx>), } @@ -96,7 +96,7 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> { // No borrowed content reachable here. } - ty::TyClosure(def_id, substs, _) => { + ty::TyClosure(def_id, ref substs) => { // TODO remove RegionSubClosure let &(r_a, opt_ty) = self.stack.last().unwrap(); self.out.push(Implication::RegionSubClosure(opt_ty, r_a, def_id, substs)); diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index a293170966a..e6cea4d1b6a 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -1374,17 +1374,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } pub fn closure_type(&self, - def_id: ast::DefId, - substs: &subst::Substs<'tcx>) - -> ty::ClosureTy<'tcx> + def_id: ast::DefId, + substs: &ty::ClosureSubsts<'tcx>) + -> ty::ClosureTy<'tcx> { - let closure_ty = self.tables .borrow() .closure_tys .get(&def_id) .unwrap() - .subst(self.tcx, substs); + .subst(self.tcx, &substs.func_substs); if self.normalize { normalize_associated_type(&self.tcx, &closure_ty) @@ -1395,7 +1394,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn closure_upvars(&self, def_id: ast::DefId, - substs: &Substs<'tcx>) + substs: &ty::ClosureSubsts<'tcx>) -> Option<Vec<ty::ClosureUpvar<'tcx>>> { let result = ty::ctxt::closure_upvars(self, def_id, substs); diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index fbb80fef9e6..7db740798bd 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1493,7 +1493,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { fn fn_ret(&self, id: NodeId) -> ty::PolyFnOutput<'tcx> { let fn_ty = self.ir.tcx.node_id_to_type(id); match fn_ty.sty { - ty::TyClosure(closure_def_id, substs, _) => + ty::TyClosure(closure_def_id, ref substs) => self.ir.tcx.closure_type(closure_def_id, substs).sig.output(), _ => fn_ty.fn_ret() } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 4ba154b1046..bf47396bb9f 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -584,7 +584,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> { def::DefUpvar(var_id, fn_node_id) => { let ty = try!(self.node_ty(fn_node_id)); match ty.sty { - ty::TyClosure(closure_id, _, _) => { + ty::TyClosure(closure_id, _) => { match self.typer.closure_kind(closure_id) { Some(kind) => { self.cat_upvar(id, span, var_id, fn_node_id, kind) diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index ea2dee76159..376430e87c6 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -270,8 +270,7 @@ pub struct VtableImplData<'tcx, N> { #[derive(Clone, PartialEq, Eq)] pub struct VtableClosureData<'tcx, N> { pub closure_def_id: ast::DefId, - pub substs: subst::Substs<'tcx>, - pub upvar_tys: Vec<Ty<'tcx>>, + pub substs: ty::ClosureSubsts<'tcx>, /// Nested obligations. This can be non-empty if the closure /// signature contains associated types. pub nested: Vec<N> @@ -550,7 +549,6 @@ impl<'tcx, N> Vtable<'tcx, N> { closure_def_id: c.closure_def_id, substs: c.substs, nested: c.nested.into_iter().map(f).collect(), - upvar_tys: c.upvar_tys, }) } } diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs index b678aa405a8..ef3a217ecdb 100644 --- a/src/librustc/middle/traits/project.rs +++ b/src/librustc/middle/traits/project.rs @@ -154,7 +154,7 @@ fn consider_unification_despite_ambiguity<'cx,'tcx>(selcx: &mut SelectionContext debug!("consider_unification_despite_ambiguity: self_ty.sty={:?}", self_ty.sty); match self_ty.sty { - ty::TyClosure(closure_def_id, substs, _) => { + ty::TyClosure(closure_def_id, ref substs) => { let closure_typer = selcx.closure_typer(); let closure_type = closure_typer.closure_type(closure_def_id, substs); let ty::Binder((_, ret_type)) = diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index af41e205aec..c2c2ceb0b03 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -201,7 +201,7 @@ enum SelectionCandidate<'tcx> { /// Implementation of a `Fn`-family trait by one of the /// anonymous types generated for a `||` expression. - ClosureCandidate(/* closure */ ast::DefId, &'tcx Substs<'tcx>, &'tcx Vec<Ty<'tcx>>), + ClosureCandidate(/* closure */ ast::DefId, &'tcx ty::ClosureSubsts<'tcx>), /// Implementation of a `Fn`-family trait by one of the anonymous /// types generated for a fn pointer type (e.g., `fn(int)->int`) @@ -348,7 +348,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // lifetimes can appear inside the self-type. let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder()); let (closure_def_id, substs) = match self_ty.sty { - ty::TyClosure(id, ref substs, _) => (id, substs.clone()), + ty::TyClosure(id, ref substs) => (id, substs), _ => { return; } }; assert!(!substs.has_escaping_regions()); @@ -1142,8 +1142,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, '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, upvar_tys) = match self_ty.sty { - ty::TyClosure(id, substs, ref upvar_tys) => (id, substs, upvar_tys), + let (closure_def_id, substs) = match self_ty.sty { + ty::TyClosure(id, ref substs) => (id, substs), ty::TyInfer(ty::TyVar(_)) => { debug!("assemble_unboxed_closure_candidates: ambiguous self-type"); candidates.ambiguous = true; @@ -1161,7 +1161,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Some(closure_kind) => { debug!("assemble_unboxed_candidates: closure_kind = {:?}", closure_kind); if closure_kind.extends(kind) { - candidates.vec.push(ClosureCandidate(closure_def_id, substs, upvar_tys)); + candidates.vec.push(ClosureCandidate(closure_def_id, substs)); } } None => { @@ -1703,7 +1703,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet ty::TyTuple(ref tys) => ok_if(tys.clone()), - ty::TyClosure(def_id, substs, _) => { + ty::TyClosure(def_id, ref substs) => { // FIXME -- This case is tricky. In the case of by-ref // closures particularly, we need the results of // inference to decide how to reflect the type of each @@ -1865,7 +1865,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Some(tys.clone()) } - ty::TyClosure(def_id, substs, _) => { + ty::TyClosure(def_id, ref substs) => { assert_eq!(def_id.krate, ast::LOCAL_CRATE); // TODO @@ -2015,10 +2015,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Ok(VtableImpl(vtable_impl)) } - ClosureCandidate(closure_def_id, substs, upvar_tys) => { + ClosureCandidate(closure_def_id, substs) => { let vtable_closure = - try!(self.confirm_closure_candidate(obligation, closure_def_id, - &substs, upvar_tys)); + try!(self.confirm_closure_candidate(obligation, closure_def_id, substs)); Ok(VtableClosure(vtable_closure)) } @@ -2367,8 +2366,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_closure_candidate(&mut self, obligation: &TraitObligation<'tcx>, closure_def_id: ast::DefId, - substs: &Substs<'tcx>, - upvar_tys: &'tcx Vec<Ty<'tcx>>) + substs: &ty::ClosureSubsts<'tcx>) -> Result<VtableClosureData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> { @@ -2394,7 +2392,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Ok(VtableClosureData { closure_def_id: closure_def_id, substs: substs.clone(), - upvar_tys: upvar_tys.clone(), nested: obligations }) } @@ -2856,7 +2853,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn closure_trait_ref_unnormalized(&mut self, obligation: &TraitObligation<'tcx>, closure_def_id: ast::DefId, - substs: &Substs<'tcx>) + substs: &ty::ClosureSubsts<'tcx>) -> ty::PolyTraitRef<'tcx> { let closure_type = self.infcx.closure_type(closure_def_id, substs); @@ -2878,7 +2875,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn closure_trait_ref(&mut self, obligation: &TraitObligation<'tcx>, closure_def_id: ast::DefId, - substs: &Substs<'tcx>) + substs: &ty::ClosureSubsts<'tcx>) -> Normalized<'tcx, ty::PolyTraitRef<'tcx>> { let trait_ref = self.closure_trait_ref_unnormalized( diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 17d55737114..5528472d793 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1767,7 +1767,7 @@ pub enum TypeVariants<'tcx> { /// The anonymous type of a closure. Used to represent the type of /// `|a| a`. - TyClosure(DefId, &'tcx Substs<'tcx>, Vec<Ty<'tcx>>), + TyClosure(DefId, Box<ClosureSubsts<'tcx>>), /// A tuple type. For example, `(i32, bool)`. TyTuple(Vec<Ty<'tcx>>), @@ -1787,6 +1787,93 @@ pub enum TypeVariants<'tcx> { TyError, } +/// A closure can be modeled as a struct that looks like: +/// +/// struct Closure<'l0...'li, T0...Tj, U0...Uk> { +/// upvar0: U0, +/// ... +/// upvark: Uk +/// } +/// +/// where 'l0...'li and T0...Tj are the lifetime and type parameters +/// in scope on the function that defined the closure, and U0...Uk are +/// type parameters representing the types of its upvars (borrowed, if +/// appropriate). +/// +/// So, for example, given this function: +/// +/// fn foo<'a, T>(data: &'a mut T) { +/// do(|| data.count += 1) +/// } +/// +/// the type of the closure would be something like: +/// +/// struct Closure<'a, T, U0> { +/// data: U0 +/// } +/// +/// Note that the type of the upvar is not specified in the struct. +/// You may wonder how the impl would then be able to use the upvar, +/// if it doesn't know it's type? The answer is that the impl is +/// (conceptually) not fully generic over Closure but rather tied to +/// instances with the expected upvar types: +/// +/// impl<'b, 'a, T> FnMut() for Closure<'a, T, &'b mut &'a mut T> { +/// ... +/// } +/// +/// You can see that the *impl* fully specified the type of the upvar +/// and thus knows full well that `data` has type `&'b mut &'a mut T`. +/// (Here, I am assuming that `data` is mut-borrowed.) +/// +/// Now, the last question you may ask is: Why include the upvar types +/// as extra type parameters? The reason for this design is that the +/// upvar types can reference lifetimes that are internal to the +/// creating function. In my example above, for example, the lifetime +/// `'b` represents the extent of the closure itself; this is some +/// subset of `foo`, probably just the extent of the call to the to +/// `do()`. If we just had the lifetime/type parameters from the +/// enclosing function, we couldn't name this lifetime `'b`. Note that +/// there can also be lifetimes in the types of the upvars themselves, +/// if one of them happens to be a reference to something that the +/// creating fn owns. +/// +/// OK, you say, so why not create a more minimal set of parameters +/// that just includes the extra lifetime parameters? The answer is +/// primarily that it would be hard --- we don't know at the time when +/// we create the closure type what the full types of the upvars are, +/// nor do we know which are borrowed and which are not. In this +/// design, we can just supply a fresh type parameter and figure that +/// out later. +/// +/// All right, you say, but why include the type parameters from the +/// original function then? The answer is that trans may need them +/// when monomorphizing, and they may not appear in the upvars. A +/// closure could capture no variables but still make use of some +/// in-scope type parameter with a bound (e.g., if our example above +/// had an extra `U: Default`, and the closure called `U::default()`). +/// +/// There is another reason. This design (implicitly) prohibits +/// closures from capturing themselves (except via a trait +/// object). This simplifies closure inference considerably, since it +/// means that when we infer the kind of a closure or its upvars, we +/// don't have to handles cycles where the decisions we make wind up +/// for closure C wind up influencing the decisions we ought to make +/// for closure C (which would then require fixed point iteration to +/// handle). Plus it fixes an ICE. :P +#[derive(Clone, PartialEq, Eq, Hash, Debug)] +pub struct ClosureSubsts<'tcx> { + /// Lifetime and type parameters from the enclosing function. + /// These are separated out because trans wants to pass them around + /// when monomorphizing. + pub func_substs: &'tcx Substs<'tcx>, + + /// The types of the upvars. The list parallels the freevars and + /// `upvar_borrows` lists. These are kept distinct so that we can + /// easily index into them. + pub upvar_tys: Vec<Ty<'tcx>> +} + #[derive(Clone, PartialEq, Eq, Hash)] pub struct TraitTy<'tcx> { pub principal: ty::PolyTraitRef<'tcx>, @@ -3214,11 +3301,11 @@ impl FlagComputation { } } - &TyClosure(_, substs, ref tys) => { + &TyClosure(_, ref substs) => { self.add_flags(TypeFlags::HAS_TY_CLOSURE); self.add_flags(TypeFlags::HAS_LOCAL_NAMES); - self.add_substs(substs); - self.add_tys(tys); + self.add_substs(&substs.func_substs); + self.add_tys(&substs.upvar_tys); } &TyInfer(_) => { @@ -3462,10 +3549,10 @@ impl<'tcx> ctxt<'tcx> { pub fn closure_type(&self, def_id: ast::DefId, - substs: &subst::Substs<'tcx>) + substs: &ClosureSubsts<'tcx>) -> ty::ClosureTy<'tcx> { - self.tables.borrow().closure_tys.get(&def_id).unwrap().subst(self, substs) + self.tables.borrow().closure_tys.get(&def_id).unwrap().subst(self, &substs.func_substs) } pub fn type_parameter_def(&self, @@ -3665,7 +3752,17 @@ impl<'tcx> ctxt<'tcx> { substs: &'tcx Substs<'tcx>, tys: Vec<Ty<'tcx>>) -> Ty<'tcx> { - self.mk_ty(TyClosure(closure_id, substs, tys)) + self.mk_closure_from_closure_substs(closure_id, Box::new(ClosureSubsts { + func_substs: substs, + upvar_tys: tys + })) + } + + pub fn mk_closure_from_closure_substs(&self, + closure_id: ast::DefId, + closure_substs: Box<ClosureSubsts<'tcx>>) + -> Ty<'tcx> { + self.mk_ty(TyClosure(closure_id, closure_substs)) } pub fn mk_var(&self, v: TyVid) -> Ty<'tcx> { @@ -3932,7 +4029,7 @@ impl<'tcx> TyS<'tcx> { TyTrait(ref tt) => Some(tt.principal_def_id()), TyStruct(id, _) | TyEnum(id, _) | - TyClosure(id, _, _) => Some(id), + TyClosure(id, _) => Some(id), _ => None } } @@ -4150,7 +4247,8 @@ impl<'tcx> TyS<'tcx> { apply_lang_items(cx, did, res) } - TyClosure(did, substs, _) => { + TyClosure(did, ref substs) => { + // TODO let param_env = cx.empty_parameter_environment(); let infcx = infer::new_infer_ctxt(cx, &cx.tables, Some(param_env), false); let upvars = infcx.closure_upvars(did, substs).unwrap(); @@ -5911,9 +6009,9 @@ impl<'tcx> ctxt<'tcx> { // Returns a list of `ClosureUpvar`s for each upvar. pub fn closure_upvars<'a>(typer: &infer::InferCtxt<'a, 'tcx>, - closure_id: ast::DefId, - substs: &Substs<'tcx>) - -> Option<Vec<ClosureUpvar<'tcx>>> + closure_id: ast::DefId, + substs: &ClosureSubsts<'tcx>) + -> Option<Vec<ClosureUpvar<'tcx>>> { // Presently an unboxed closure type cannot "escape" out of a // function, so we will only encounter ones that originated in the @@ -5932,7 +6030,7 @@ impl<'tcx> ctxt<'tcx> { Ok(t) => { t } Err(()) => { return None; } }; - let freevar_ty = freevar_ty.subst(tcx, substs); + let freevar_ty = freevar_ty.subst(tcx, &substs.func_substs); let upvar_id = ty::UpvarId { var_id: freevar_def_id.node, @@ -6382,7 +6480,7 @@ impl<'tcx> ctxt<'tcx> { } TyInfer(_) => unreachable!(), TyError => byte!(21), - TyClosure(d, _, _) => { + TyClosure(d, _) => { byte!(22); did(state, d); } @@ -6763,6 +6861,13 @@ impl<'tcx> RegionEscape for Substs<'tcx> { } } +impl<'tcx> RegionEscape for ClosureSubsts<'tcx> { + fn has_regions_escaping_depth(&self, depth: u32) -> bool { + self.func_substs.has_regions_escaping_depth(depth) || + self.upvar_tys.iter().any(|t| t.has_regions_escaping_depth(depth)) + } +} + impl<T:RegionEscape> RegionEscape for Vec<T> { fn has_regions_escaping_depth(&self, depth: u32) -> bool { self.iter().any(|t| t.has_regions_escaping_depth(depth)) @@ -7106,6 +7211,15 @@ impl<'tcx> HasTypeFlags for BareFnTy<'tcx> { } } +impl<'tcx> HasTypeFlags for ClosureSubsts<'tcx> { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.func_substs.has_type_flags(flags) || + self.upvar_tys.iter().any(|t| t.has_type_flags(flags)) + } +} + + + impl<'tcx> fmt::Debug for ClosureTy<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "ClosureTy({},{:?},{})", diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index 87b5fcbd28e..b6bb82ad7b1 100644 --- a/src/librustc/middle/ty_fold.rs +++ b/src/librustc/middle/ty_fold.rs @@ -296,6 +296,16 @@ impl<'tcx> TypeFoldable<'tcx> for subst::Substs<'tcx> { } } +impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> { + fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::ClosureSubsts<'tcx> { + let func_substs = self.func_substs.fold_with(folder); + ty::ClosureSubsts { + func_substs: folder.tcx().mk_substs(func_substs), + upvar_tys: self.upvar_tys.fold_with(folder), + } + } +} + impl<'tcx> TypeFoldable<'tcx> for ty::ItemSubsts<'tcx> { fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::ItemSubsts<'tcx> { ty::ItemSubsts { @@ -450,7 +460,6 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableClosureDa closure_def_id: self.closure_def_id, substs: self.substs.fold_with(folder), nested: self.nested.fold_with(folder), - upvar_tys: self.upvar_tys.fold_with(folder), } } } @@ -603,10 +612,9 @@ pub fn super_fold_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T, let substs = substs.fold_with(this); ty::TyStruct(did, this.tcx().mk_substs(substs)) } - ty::TyClosure(did, ref substs, ref tys) => { + ty::TyClosure(did, ref substs) => { let s = substs.fold_with(this); - let tys = tys.fold_with(this); - ty::TyClosure(did, this.tcx().mk_substs(s), tys) + ty::TyClosure(did, s) } ty::TyProjection(ref data) => { ty::TyProjection(data.fold_with(this)) diff --git a/src/librustc/middle/ty_relate/mod.rs b/src/librustc/middle/ty_relate/mod.rs index 33cddc978d9..f8678b4d8e3 100644 --- a/src/librustc/middle/ty_relate/mod.rs +++ b/src/librustc/middle/ty_relate/mod.rs @@ -506,16 +506,15 @@ pub fn super_relate_tys<'a,'tcx:'a,R>(relation: &mut R, Ok(tcx.mk_struct(a_id, tcx.mk_substs(substs))) } - (&ty::TyClosure(a_id, a_substs, ref a_tys), - &ty::TyClosure(b_id, b_substs, ref b_tys)) + (&ty::TyClosure(a_id, ref a_substs), + &ty::TyClosure(b_id, ref b_substs)) if a_id == b_id => { // All TyClosure types with the same id represent // the (anonymous) type of the same closure expression. So // all of their regions should be equated. - let substs = try!(relate_substs(relation, None, a_substs, b_substs)); - let tys = try!(relation.relate_zip(a_tys, b_tys)); - Ok(tcx.mk_closure(a_id, tcx.mk_substs(substs), tys)) + let substs = try!(relation.relate(a_substs, b_substs)); + Ok(tcx.mk_closure_from_closure_substs(a_id, substs)) } (&ty::TyBox(a_inner), &ty::TyBox(b_inner)) => @@ -588,6 +587,20 @@ pub fn super_relate_tys<'a,'tcx:'a,R>(relation: &mut R, } } +impl<'a,'tcx:'a> Relate<'a,'tcx> for ty::ClosureSubsts<'tcx> { + fn relate<R>(relation: &mut R, + a: &ty::ClosureSubsts<'tcx>, + b: &ty::ClosureSubsts<'tcx>) + -> RelateResult<'tcx, ty::ClosureSubsts<'tcx>> + where R: TypeRelation<'a,'tcx> + { + let func_substs = try!(relate_substs(relation, None, a.func_substs, b.func_substs)); + let upvar_tys = try!(relation.relate_zip(&a.upvar_tys, &b.upvar_tys)); + Ok(ty::ClosureSubsts { func_substs: relation.tcx().mk_substs(func_substs), + upvar_tys: upvar_tys }) + } +} + impl<'a,'tcx:'a> Relate<'a,'tcx> for ty::Region { fn relate<R>(relation: &mut R, a: &ty::Region, diff --git a/src/librustc/middle/ty_walk.rs b/src/librustc/middle/ty_walk.rs index 97f3bd12971..81cad448690 100644 --- a/src/librustc/middle/ty_walk.rs +++ b/src/librustc/middle/ty_walk.rs @@ -91,9 +91,9 @@ fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) { ty::TyStruct(_, ref substs) => { push_reversed(stack, substs.types.as_slice()); } - ty::TyClosure(_, ref substs, ref tys) => { - push_reversed(stack, substs.types.as_slice()); - push_reversed(stack, tys); + ty::TyClosure(_, ref substs) => { + push_reversed(stack, substs.func_substs.types.as_slice()); + push_reversed(stack, &substs.upvar_tys); } ty::TyTuple(ref ts) => { push_reversed(stack, ts); diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index d6696e392bc..d24fa5cef03 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -662,11 +662,14 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> { TyTrait(ref data) => write!(f, "{}", data), ty::TyProjection(ref data) => write!(f, "{}", data), TyStr => write!(f, "str"), - TyClosure(ref did, substs, _) => ty::tls::with(|tcx| { + TyClosure(ref did, ref substs) => ty::tls::with(|tcx| { try!(write!(f, "[closure")); + + // TODO consider changing this to print out the upvar types instead + let closure_tys = &tcx.tables.borrow().closure_tys; try!(closure_tys.get(did).map(|cty| &cty.sig).and_then(|sig| { - tcx.lift(&substs).map(|substs| sig.subst(tcx, substs)) + tcx.lift(&substs.func_substs).map(|substs| sig.subst(tcx, substs)) }).map(|sig| { fn_sig(f, &sig.0.inputs, false, sig.0.output) }).unwrap_or_else(|| { diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 331bcaa8da8..6289d505881 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -2529,7 +2529,7 @@ impl LintPass for DropWithReprExtern { match dtor_self_type.sty { ty::TyEnum(self_type_did, _) | ty::TyStruct(self_type_did, _) | - ty::TyClosure(self_type_did, _, _) => { + ty::TyClosure(self_type_did, _) => { let hints = ctx.tcx.lookup_repr_hints(self_type_did); if hints.iter().any(|attr| *attr == attr::ReprExtern) && ctx.tcx.ty_dtor(self_type_did).has_drop_flag() { diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs index 985ef2d7b14..b51a3d4b2a0 100644 --- a/src/librustc_trans/trans/adt.rs +++ b/src/librustc_trans/trans/adt.rs @@ -221,7 +221,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, Univariant(mk_struct(cx, &ftys[..], packed, t), dtor_to_init_u8(dtor)) } - ty::TyClosure(def_id, substs, _) => { + ty::TyClosure(def_id, ref substs) => { let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables); let upvars = infcx.closure_upvars(def_id, substs).unwrap(); // TODO let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>(); @@ -441,7 +441,7 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>, // Perhaps one of the upvars of this struct is non-zero // Let's recurse and find out! - ty::TyClosure(def_id, substs, _) => { + ty::TyClosure(def_id, ref substs) => { let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables); let upvars = infcx.closure_upvars(def_id, substs).unwrap(); // TODO let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>(); diff --git a/src/librustc_trans/trans/attributes.rs b/src/librustc_trans/trans/attributes.rs index 03e7d9e3aa2..62b03c9fb0f 100644 --- a/src/librustc_trans/trans/attributes.rs +++ b/src/librustc_trans/trans/attributes.rs @@ -145,7 +145,7 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx let function_type; let (fn_sig, abi, env_ty) = match fn_type.sty { ty::TyBareFn(_, ref f) => (&f.sig, f.abi, None), - ty::TyClosure(closure_did, substs, _) => { + ty::TyClosure(closure_did, ref substs) => { let infcx = infer::normalizing_infer_ctxt(ccx.tcx(), &ccx.tcx().tables); function_type = infcx.closure_type(closure_did, substs); let self_type = base::self_type_for_closure(ccx, closure_did, fn_type); diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 678b5063816..e18fc6c5da2 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -470,7 +470,7 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>, } }) } - ty::TyClosure(def_id, substs, _) => { // TODO + ty::TyClosure(def_id, ref substs) => { // TODO let repr = adt::represent_type(cx.ccx(), t); let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables); let upvars = infcx.closure_upvars(def_id, substs).unwrap(); diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index 7900000d3a9..0f75c1f8ab6 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -32,7 +32,6 @@ use trans::build::*; use trans::callee; use trans::cleanup; use trans::cleanup::CleanupMethods; -use trans::closure; use trans::common::{self, Block, Result, NodeIdAndSpan, ExprId, CrateContext, ExprOrMethodCall, FunctionContext, MethodCallKey}; use trans::consts; @@ -446,12 +445,6 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>( } }; - // If this is a closure, redirect to it. - match closure::get_or_create_declaration_if_closure(ccx, def_id, substs) { - None => {} - Some(llfn) => return llfn, - } - // Check whether this fn has an inlined copy and, if so, redirect // def_id to the local id of the inlined copy. let def_id = inline::maybe_instantiate_inline(ccx, def_id); diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index defa0a1d898..b05bc7e5855 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -12,7 +12,6 @@ use arena::TypedArena; use back::link::{self, mangle_internal_name_by_path_and_seq}; use llvm::{ValueRef, get_params}; use middle::infer; -use middle::ty::Ty; use trans::adt; use trans::attributes; use trans::base::*; @@ -24,10 +23,9 @@ use trans::datum::{self, Datum, rvalue_scratch_datum, Rvalue, ByValue}; use trans::debuginfo::{self, DebugLoc}; use trans::declare; use trans::expr; -use trans::monomorphize::{self, MonoId}; +use trans::monomorphize::{MonoId}; use trans::type_of::*; use middle::ty; -use middle::subst::Substs; use session::config::FullDebugInfo; use syntax::abi::RustCall; @@ -127,47 +125,32 @@ impl<'a> ClosureEnv<'a> { /// Returns the LLVM function declaration for a closure, creating it if /// necessary. If the ID does not correspond to a closure ID, returns None. -pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - closure_id: ast::DefId, - substs: &Substs<'tcx>) - -> Option<Datum<'tcx, Rvalue>> { - if !ccx.tcx().tables.borrow().closure_kinds.contains_key(&closure_id) { - // Not a closure. - return None - } - - let function_type = ccx.tcx().node_id_to_type(closure_id.node); - let function_type = monomorphize::apply_param_substs(ccx.tcx(), substs, &function_type); - +pub fn get_or_create_closure_declaration<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, + closure_id: ast::DefId, + substs: &ty::ClosureSubsts<'tcx>) + -> ValueRef { // Normalize type so differences in regions and typedefs don't cause // duplicate declarations - let function_type = erase_regions(ccx.tcx(), &function_type); - let params = match function_type.sty { - ty::TyClosure(_, substs, _) => &substs.types, - _ => unreachable!() - }; + let substs = erase_regions(ccx.tcx(), substs); let mono_id = MonoId { def: closure_id, - params: params + params: &substs.func_substs.types }; - match ccx.closure_vals().borrow().get(&mono_id) { - Some(&llfn) => { - debug!("get_or_create_declaration_if_closure(): found closure {:?}: {:?}", - mono_id, ccx.tn().val_to_string(llfn)); - return Some(Datum::new(llfn, function_type, Rvalue::new(ByValue))) - } - None => {} + if let Some(&llfn) = ccx.closure_vals().borrow().get(&mono_id) { + debug!("get_or_create_declaration_if_closure(): found closure {:?}: {:?}", + mono_id, ccx.tn().val_to_string(llfn)); + return llfn; } let symbol = ccx.tcx().map.with_path(closure_id.node, |path| { mangle_internal_name_by_path_and_seq(path, "closure") }); - // Currently there’s only a single user of - // get_or_create_declaration_if_closure and it unconditionally defines the - // function, therefore we use define_* here. - let llfn = declare::define_internal_rust_fn(ccx, &symbol[..], function_type); + let function_type = ccx.tcx().mk_closure_from_closure_substs(closure_id, Box::new(substs)); + let llfn = declare::define_internal_rust_fn(ccx, &symbol[..], function_type).unwrap_or_else(||{ + ccx.sess().bug(&format!("symbol `{}` already defined", symbol)); + }); // set an inline hint for all closures attributes::inline(llfn, attributes::InlineAttr::Hint); @@ -179,7 +162,7 @@ pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tc ccx.tn().val_to_string(llfn)); ccx.closure_vals().borrow_mut().insert(mono_id, llfn); - Some(Datum::new(llfn, function_type, Rvalue::new(ByValue))) + llfn } pub enum Dest<'a, 'tcx: 'a> { @@ -191,9 +174,11 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>, decl: &ast::FnDecl, body: &ast::Block, id: ast::NodeId, - param_substs: &'tcx Substs<'tcx>) + closure_substs: &'tcx ty::ClosureSubsts<'tcx>) -> Option<Block<'a, 'tcx>> { + let param_substs = closure_substs.func_substs; + let ccx = match dest { Dest::SaveIn(bcx, _) => bcx.ccx(), Dest::Ignore(ccx) => ccx @@ -204,10 +189,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>, debug!("trans_closure_expr()"); let closure_id = ast_util::local_def(id); - let llfn = get_or_create_declaration_if_closure( - ccx, - closure_id, - param_substs).unwrap(); + let llfn = get_or_create_closure_declaration(ccx, closure_id, closure_substs); // Get the type of this closure. Use the current `param_substs` as // the closure substitutions. This makes sense because the closure @@ -216,7 +198,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>, // of the closure expression. let infcx = infer::normalizing_infer_ctxt(ccx.tcx(), &ccx.tcx().tables); - let function_type = infcx.closure_type(closure_id, param_substs); + let function_type = infcx.closure_type(closure_id, closure_substs); let freevars: Vec<ty::Freevar> = tcx.with_freevars(id, |fv| fv.iter().cloned().collect()); @@ -226,7 +208,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>, trans_closure(ccx, decl, body, - llfn.val, + llfn, param_substs, id, &[], @@ -269,20 +251,12 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>, pub fn trans_closure_method<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>, closure_def_id: ast::DefId, - substs: Substs<'tcx>, - upvar_tys: Vec<Ty<'tcx>>, - node: ExprOrMethodCall, - param_substs: &'tcx Substs<'tcx>, + substs: ty::ClosureSubsts<'tcx>, trait_closure_kind: ty::ClosureKind) -> ValueRef { - // The substitutions should have no type parameters remaining - // after passing through fulfill_obligation - let llfn = callee::trans_fn_ref_with_substs(ccx, - closure_def_id, - node, - param_substs, - substs.clone()).val; + // If this is a closure, redirect to it. + let llfn = get_or_create_closure_declaration(ccx, closure_def_id, &substs); // If the closure is a Fn closure, but a FnOnce is needed (etc), // then adapt the self type @@ -290,7 +264,6 @@ pub fn trans_closure_method<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>, trans_closure_adapter_shim(ccx, closure_def_id, substs, - upvar_tys, closure_kind, trait_closure_kind, llfn) @@ -299,8 +272,7 @@ pub fn trans_closure_method<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>, fn trans_closure_adapter_shim<'a, 'tcx>( ccx: &'a CrateContext<'a, 'tcx>, closure_def_id: ast::DefId, - substs: Substs<'tcx>, - upvar_tys: Vec<Ty<'tcx>>, + substs: ty::ClosureSubsts<'tcx>, llfn_closure_kind: ty::ClosureKind, trait_closure_kind: ty::ClosureKind, llfn: ValueRef) @@ -339,7 +311,7 @@ fn trans_closure_adapter_shim<'a, 'tcx>( // fn call_once(mut self, ...) { call_mut(&mut self, ...) } // // These are both the same at trans time. - trans_fn_once_adapter_shim(ccx, closure_def_id, substs, upvar_tys, llfn) + trans_fn_once_adapter_shim(ccx, closure_def_id, substs, llfn) } _ => { tcx.sess.bug(&format!("trans_closure_adapter_shim: cannot convert {:?} to {:?}", @@ -352,8 +324,7 @@ fn trans_closure_adapter_shim<'a, 'tcx>( fn trans_fn_once_adapter_shim<'a, 'tcx>( ccx: &'a CrateContext<'a, 'tcx>, closure_def_id: ast::DefId, - substs: Substs<'tcx>, - upvar_tys: Vec<Ty<'tcx>>, + substs: ty::ClosureSubsts<'tcx>, llreffn: ValueRef) -> ValueRef { @@ -367,12 +338,11 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>( // Find a version of the closure type. Substitute static for the // region since it doesn't really matter. - let substs = tcx.mk_substs(substs); - let closure_ty = tcx.mk_closure(closure_def_id, substs, upvar_tys); + let closure_ty = tcx.mk_closure_from_closure_substs(closure_def_id, Box::new(substs.clone())); let ref_closure_ty = tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic), closure_ty); // Make a version with the type of by-ref closure. - let ty::ClosureTy { unsafety, abi, mut sig } = infcx.closure_type(closure_def_id, substs); + let ty::ClosureTy { unsafety, abi, mut sig } = infcx.closure_type(closure_def_id, &substs); sig.0.inputs.insert(0, ref_closure_ty); // sig has no self type as of yet let llref_bare_fn_ty = tcx.mk_bare_fn(ty::BareFnTy { unsafety: unsafety, abi: abi, @@ -402,7 +372,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>( ast::DUMMY_NODE_ID, false, sig.output, - substs, + substs.func_substs, None, &block_arena); let mut bcx = init_function(&fcx, false, sig.output); diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index 302ef68bddc..deab11332c8 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -882,11 +882,16 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } }, ast::ExprClosure(_, ref decl, ref body) => { - closure::trans_closure_expr(closure::Dest::Ignore(cx), - decl, - body, - e.id, - param_substs); + match ety.sty { + ty::TyClosure(_, ref substs) => { + closure::trans_closure_expr(closure::Dest::Ignore(cx), decl, + body, e.id, substs); + } + _ => + cx.sess().span_bug( + e.span, + &format!("bad type for closure expr: {:?}", ety)) + } C_null(type_of::type_of(cx, ety)) }, _ => cx.sess().span_bug(e.span, diff --git a/src/librustc_trans/trans/debuginfo/metadata.rs b/src/librustc_trans/trans/debuginfo/metadata.rs index d0c6c0ab308..66772e67755 100644 --- a/src/librustc_trans/trans/debuginfo/metadata.rs +++ b/src/librustc_trans/trans/debuginfo/metadata.rs @@ -287,7 +287,7 @@ impl<'tcx> TypeMap<'tcx> { } } }, - ty::TyClosure(def_id, substs, _) => { + ty::TyClosure(def_id, ref substs) => { let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables); let closure_ty = infcx.closure_type(def_id, substs); self.get_unique_type_id_of_closure_type(cx, @@ -811,7 +811,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, MetadataCreationResult::new(pointer_type_metadata(cx, t, fn_metadata), false) } - ty::TyClosure(def_id, substs, _) => { + ty::TyClosure(def_id, ref substs) => { let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables); let upvars = infcx.closure_upvars(def_id, substs).unwrap(); let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>(); diff --git a/src/librustc_trans/trans/declare.rs b/src/librustc_trans/trans/declare.rs index a641302e53f..0c77e74be38 100644 --- a/src/librustc_trans/trans/declare.rs +++ b/src/librustc_trans/trans/declare.rs @@ -116,7 +116,7 @@ pub fn declare_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str, ty::TyBareFn(_, ref f) => { (&f.sig, f.abi, None) } - ty::TyClosure(closure_did, substs, _) => { + ty::TyClosure(closure_did, ref substs) => { let infcx = infer::normalizing_infer_ctxt(ccx.tcx(), &ccx.tcx().tables); function_type = infcx.closure_type(closure_did, substs); let self_type = base::self_type_for_closure(ccx, closure_did, fn_type); diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index f7ace785120..962803932b8 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -1146,8 +1146,14 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, SaveIn(lldest) => closure::Dest::SaveIn(bcx, lldest), Ignore => closure::Dest::Ignore(bcx.ccx()) }; - closure::trans_closure_expr(dest, decl, body, expr.id, bcx.fcx.param_substs) - .unwrap_or(bcx) + let substs = match expr_ty(bcx, expr).sty { + ty::TyClosure(_, ref substs) => substs, + ref t => + bcx.tcx().sess.span_bug( + expr.span, + &format!("closure expr without closure type: {:?}", t)), + }; + closure::trans_closure_expr(dest, decl, body, expr.id, substs).unwrap_or(bcx) } ast::ExprCall(ref f, ref args) => { if bcx.tcx().is_method_call(expr.id) { diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index cf2a226db41..4a549d9c24c 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -341,9 +341,6 @@ fn trans_monomorphized_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let llfn = closure::trans_closure_method(bcx.ccx(), vtable_closure.closure_def_id, vtable_closure.substs, - vtable_closure.upvar_tys, - MethodCallKey(method_call), - bcx.fcx.param_substs, trait_closure_kind); Callee { bcx: bcx, @@ -642,15 +639,11 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, traits::VtableClosureData { closure_def_id, substs, - upvar_tys, nested: _ }) => { let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_ref.def_id()).unwrap(); let llfn = closure::trans_closure_method(ccx, closure_def_id, substs, - upvar_tys, - ExprId(0), - param_substs, trait_closure_kind); vec![llfn].into_iter() } diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 955a3013405..4cca3b7582b 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -131,7 +131,7 @@ fn try_overloaded_call_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, return Some(CallStep::Builtin); } - ty::TyClosure(def_id, substs, _) => { + ty::TyClosure(def_id, ref substs) => { assert_eq!(def_id.krate, ast::LOCAL_CRATE); // Check whether this is a call to a closure where we diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index f37177684d5..38207354792 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -41,8 +41,7 @@ pub fn check_drop_impl(tcx: &ty::ctxt, drop_impl_did: ast::DefId) -> Result<(), let dtor_predicates = tcx.lookup_predicates(drop_impl_did); match dtor_self_type.sty { ty::TyEnum(self_type_did, self_to_impl_substs) | - ty::TyStruct(self_type_did, self_to_impl_substs) | - ty::TyClosure(self_type_did, self_to_impl_substs, _) => { + ty::TyStruct(self_type_did, self_to_impl_substs) => { try!(ensure_drop_params_and_item_params_correspond(tcx, drop_impl_did, dtor_generics, diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 8b9871428c4..a960123efc6 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -288,7 +288,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { } ty::TyEnum(did, _) | ty::TyStruct(did, _) | - ty::TyClosure(did, _, _) => { + ty::TyClosure(did, _) => { self.assemble_inherent_impl_candidates_for_type(did); } ty::TyBox(_) => { @@ -711,7 +711,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { let steps = self.steps.clone(); for step in steps.iter() { let closure_def_id = match step.self_ty.sty { - ty::TyClosure(a, _, _) => a, + ty::TyClosure(a, _) => a, _ => continue, }; diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 1c21813fc63..ba89908bbe7 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -89,7 +89,6 @@ use middle::free_region::FreeRegionMap; use middle::implicator; use middle::mem_categorization as mc; use middle::region::CodeExtent; -use middle::subst::Substs; use middle::traits; use middle::ty::{self, ReScope, Ty, MethodCall, HasTypeFlags}; use middle::infer::{self, GenericKind}; @@ -1444,7 +1443,7 @@ fn closure_must_outlive<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>, origin: infer::SubregionOrigin<'tcx>, region: ty::Region, def_id: ast::DefId, - substs: &'tcx Substs<'tcx>) { + substs: &'tcx ty::ClosureSubsts<'tcx>) { debug!("closure_must_outlive(region={:?}, def_id={:?}, substs={:?})", region, def_id, substs); diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 0878ca1c295..2b800bd9a44 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -312,7 +312,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { match self_type.ty.sty { ty::TyEnum(type_def_id, _) | ty::TyStruct(type_def_id, _) | - ty::TyClosure(type_def_id, _, _) => { + ty::TyClosure(type_def_id, _) => { tcx.destructor_for_type .borrow_mut() .insert(type_def_id, method_def_id.def_id()); |
