Use a struct rather than a 4-tuple

This commit is contained in:
Niko Matsakis 2014-11-03 17:36:30 -05:00
parent fb9d0ccc2f
commit 3c84e31721
2 changed files with 44 additions and 12 deletions

View File

@ -282,6 +282,17 @@ pub struct VecPerParamSpace<T> {
content: Vec<T>,
}
/**
* The `split` function converts one `VecPerParamSpace` into this
* `SeparateVecsPerParamSpace` structure.
*/
pub struct SeparateVecsPerParamSpace<T> {
pub types: Vec<T>,
pub selfs: Vec<T>,
pub assocs: Vec<T>,
pub fns: Vec<T>,
}
impl<T:fmt::Show> fmt::Show for VecPerParamSpace<T> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
try!(write!(fmt, "VecPerParamSpace {{"));
@ -464,24 +475,30 @@ pub fn map<U>(&self, pred: |&T| -> U) -> VecPerParamSpace<U> {
}
pub fn map_move<U>(self, pred: |T| -> U) -> VecPerParamSpace<U> {
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<T>, Vec<T>, Vec<T>, Vec<T>) {
pub fn split(self) -> SeparateVecsPerParamSpace<T> {
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<T>)

View File

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