diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs index bf937439981..a7120080eed 100644 --- a/src/librustc/middle/subst.rs +++ b/src/librustc/middle/subst.rs @@ -282,6 +282,17 @@ pub struct VecPerParamSpace { content: Vec, } +/** + * The `split` function converts one `VecPerParamSpace` into this + * `SeparateVecsPerParamSpace` structure. + */ +pub struct SeparateVecsPerParamSpace { + pub types: Vec, + pub selfs: Vec, + pub assocs: Vec, + pub fns: Vec, +} + impl fmt::Show for VecPerParamSpace { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { try!(write!(fmt, "VecPerParamSpace {{")); @@ -464,24 +475,30 @@ pub fn map(&self, pred: |&T| -> U) -> VecPerParamSpace { } pub fn map_move(self, pred: |T| -> U) -> VecPerParamSpace { - let (t, s, a, f) = self.split(); + let SeparateVecsPerParamSpace { + types: t, + selfs: s, + assocs: a, + fns: f + } = self.split(); + VecPerParamSpace::new(t.into_iter().map(|p| pred(p)).collect(), s.into_iter().map(|p| pred(p)).collect(), a.into_iter().map(|p| pred(p)).collect(), f.into_iter().map(|p| pred(p)).collect()) } - pub fn split(self) -> (Vec, Vec, Vec, Vec) { + pub fn split(self) -> SeparateVecsPerParamSpace { let VecPerParamSpace { type_limit, self_limit, assoc_limit, content } = self; let mut content_iter = content.into_iter(); - let types = content_iter.by_ref().take(type_limit).collect(); - let selfs = content_iter.by_ref().take(self_limit - type_limit).collect(); - let assocs = content_iter.by_ref().take(assoc_limit - self_limit).collect(); - let fns = content_iter.collect(); - - (types, selfs, assocs, fns) + SeparateVecsPerParamSpace { + types: content_iter.by_ref().take(type_limit).collect(), + selfs: content_iter.by_ref().take(self_limit - type_limit).collect(), + assocs: content_iter.by_ref().take(assoc_limit - self_limit).collect(), + fns: content_iter.collect() + } } pub fn with_vec(mut self, space: ParamSpace, vec: Vec) diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index e54d50c8b5f..fbd4db959ce 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -205,7 +205,12 @@ pub fn trans_static_method_callee(bcx: Block, // type parameters that belong to the trait but also some that // belong to the method: let rcvr_substs = node_id_substs(bcx, ExprId(expr_id)); - let (rcvr_type, rcvr_self, rcvr_assoc, rcvr_method) = rcvr_substs.types.split(); + let subst::SeparateVecsPerParamSpace { + types: rcvr_type, + selfs: rcvr_self, + assocs: rcvr_assoc, + fns: rcvr_method + } = rcvr_substs.types.split(); // Lookup the precise impl being called. To do that, we need to // create a trait reference identifying the self type and other @@ -266,7 +271,12 @@ pub fn trans_static_method_callee(bcx: Block, // that with the `rcvr_method` from before, which tells us // the type parameters from the *method*, to yield // `callee_substs=[[T=int],[],[U=String]]`. - let (impl_type, impl_self, impl_assoc, _) = impl_substs.types.split(); + let subst::SeparateVecsPerParamSpace { + types: impl_type, + selfs: impl_self, + assocs: impl_assoc, + fns: _ + } = impl_substs.types.split(); let callee_substs = Substs::erased(VecPerParamSpace::new(impl_type, impl_self, @@ -399,8 +409,13 @@ fn combine_impl_and_methods_tps(bcx: Block, // Break apart the type parameters from the node and type // parameters from the receiver. - let (_, _, _, node_method) = node_substs.types.split(); - let (rcvr_type, rcvr_self, rcvr_assoc, rcvr_method) = rcvr_substs.types.clone().split(); + let node_method = node_substs.types.split().fns; + let subst::SeparateVecsPerParamSpace { + types: rcvr_type, + selfs: rcvr_self, + assocs: rcvr_assoc, + fns: rcvr_method + } = rcvr_substs.types.clone().split(); assert!(rcvr_method.is_empty()); subst::Substs { regions: subst::ErasedRegions,