diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 1f36c3850cf4b..b207543398aaa 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -100,7 +100,7 @@ fn enc_vec_per_param_space(w: &mut MemWriter, op: |&mut MemWriter, &ctxt, &T|) { for &space in subst::ParamSpace::all().iter() { mywrite!(w, "["); - for t in v.get_vec(space).iter() { + for t in v.get_slice(space).iter() { op(w, cx, t); } mywrite!(w, "]"); diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 19e7b9329b1ff..d7a7d2902b491 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -810,7 +810,7 @@ fn encode_vec_per_param_space(ebml_w: &mut Encoder, v: &subst::VecPerParamSpace, f: |&mut Encoder, &T|) { for &space in subst::ParamSpace::all().iter() { - ebml_w.emit_from_vec(v.get_vec(space).as_slice(), + ebml_w.emit_from_vec(v.get_slice(space), |ebml_w, n| Ok(f(ebml_w, n))).unwrap(); } } diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs index 0cd3b6e7d7918..4684bd3532ec1 100644 --- a/src/librustc/middle/subst.rs +++ b/src/librustc/middle/subst.rs @@ -15,7 +15,6 @@ use middle::ty_fold; use middle::ty_fold::{TypeFoldable, TypeFolder}; use util::ppaux::Repr; -use std::iter::Chain; use std::mem; use std::raw; use std::slice::{Items, MutItems}; @@ -191,8 +190,8 @@ impl Substs { } pub fn with_method_from(self, substs: &Substs) -> Substs { - self.with_method((*substs.types.get_vec(FnSpace)).clone(), - (*substs.regions().get_vec(FnSpace)).clone()) + self.with_method(Vec::from_slice(substs.types.get_slice(FnSpace)), + Vec::from_slice(substs.regions().get_slice(FnSpace))) } pub fn with_method(self, @@ -261,13 +260,44 @@ impl ParamSpace { */ #[deriving(PartialEq, Eq, Clone, Hash, Encodable, Decodable)] pub struct VecPerParamSpace { - vecs: (Vec, Vec, Vec) + // This was originally represented as a tuple with one Vec for + // each variant of ParamSpace, and that remains the abstraction + // that it provides to its clients. + // + // Here is how the representation corresponds to the abstraction + // i.e. the "abstraction function" AF: + // + // AF(self) = (self.content.slice_to(self.type_limit), + // self.content.slice(self.type_limit, self.self_limit), + // self.content.slice_from(self.self_limit)) + type_limit: uint, + self_limit: uint, + content: Vec, +} + +impl VecPerParamSpace { + pub fn push_all(&mut self, space: ParamSpace, values: &[T]) { + // FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n). + for t in values.iter() { + self.push(space, t.clone()); + } + } } impl VecPerParamSpace { + fn limits(&self, space: ParamSpace) -> (uint, uint) { + match space { + TypeSpace => (0, self.type_limit), + SelfSpace => (self.type_limit, self.self_limit), + FnSpace => (self.self_limit, self.content.len()), + } + } + pub fn empty() -> VecPerParamSpace { VecPerParamSpace { - vecs: (Vec::new(), Vec::new(), Vec::new()) + type_limit: 0, + self_limit: 0, + content: Vec::new() } } @@ -276,8 +306,15 @@ impl VecPerParamSpace { } pub fn new(t: Vec, s: Vec, f: Vec) -> VecPerParamSpace { + let type_limit = t.len(); + let self_limit = t.len() + s.len(); + let mut content = t; + content.push_all_move(s); + content.push_all_move(f); VecPerParamSpace { - vecs: (t, s, f) + type_limit: type_limit, + self_limit: self_limit, + content: content, } } @@ -289,55 +326,98 @@ impl VecPerParamSpace { result } + /// Appends `value` to the vector associated with `space`. + /// + /// Unlike the `push` method in `Vec`, this should not be assumed + /// to be a cheap operation (even when amortized over many calls). pub fn push(&mut self, space: ParamSpace, value: T) { - self.get_mut_vec(space).push(value); + let (_, limit) = self.limits(space); + match space { + TypeSpace => { self.type_limit += 1; self.self_limit += 1; } + SelfSpace => { self.self_limit += 1; } + FnSpace => {} + } + self.content.insert(limit, value); + } + + pub fn pop(&mut self, space: ParamSpace) -> Option { + let (start, limit) = self.limits(space); + if start == limit { + None + } else { + match space { + TypeSpace => { self.type_limit -= 1; self.self_limit -= 1; } + SelfSpace => { self.self_limit -= 1; } + FnSpace => {} + } + self.content.remove(limit - 1) + } + } + + pub fn truncate(&mut self, space: ParamSpace, len: uint) { + // FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n). + while self.len(space) > len { + self.pop(space); + } + } + + pub fn replace(&mut self, space: ParamSpace, elems: Vec) { + // FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n). + self.truncate(space, 0); + for t in elems.move_iter() { + self.push(space, t); + } } pub fn get_self<'a>(&'a self) -> Option<&'a T> { - let v = self.get_vec(SelfSpace); + let v = self.get_slice(SelfSpace); assert!(v.len() <= 1); - if v.len() == 0 { None } else { Some(v.get(0)) } + if v.len() == 0 { None } else { Some(&v[0]) } } pub fn len(&self, space: ParamSpace) -> uint { - self.get_vec(space).len() + self.get_slice(space).len() + } + + pub fn is_empty_in(&self, space: ParamSpace) -> bool { + self.len(space) == 0 } - pub fn get_vec<'a>(&'a self, space: ParamSpace) -> &'a Vec { - self.vecs.get(space as uint).unwrap() + pub fn get_slice<'a>(&'a self, space: ParamSpace) -> &'a [T] { + let (start, limit) = self.limits(space); + self.content.slice(start, limit) } - pub fn get_mut_vec<'a>(&'a mut self, space: ParamSpace) -> &'a mut Vec { - self.vecs.get_mut(space as uint).unwrap() + fn get_mut_slice<'a>(&'a mut self, space: ParamSpace) -> &'a mut [T] { + let (start, limit) = self.limits(space); + self.content.mut_slice(start, limit) } pub fn opt_get<'a>(&'a self, space: ParamSpace, index: uint) -> Option<&'a T> { - let v = self.get_vec(space); - if index < v.len() { Some(v.get(index)) } else { None } + let v = self.get_slice(space); + if index < v.len() { Some(&v[index]) } else { None } } pub fn get<'a>(&'a self, space: ParamSpace, index: uint) -> &'a T { - self.get_vec(space).get(index) + &self.get_slice(space)[index] } pub fn get_mut<'a>(&'a mut self, space: ParamSpace, index: uint) -> &'a mut T { - self.get_mut_vec(space).get_mut(index) + &mut self.get_mut_slice(space)[index] } - pub fn iter<'a>(&'a self) -> Chain, - Chain, - Items<'a,T>>> { - let (ref r, ref s, ref f) = self.vecs; - r.iter().chain(s.iter().chain(f.iter())) + pub fn iter<'a>(&'a self) -> Items<'a,T> { + self.content.iter() } - pub fn all_vecs(&self, pred: |&Vec| -> bool) -> bool { - self.vecs.iter().all(pred) + pub fn all_vecs(&self, pred: |&[T]| -> bool) -> bool { + let spaces = [TypeSpace, SelfSpace, FnSpace]; + spaces.iter().all(|&space| { pred(self.get_slice(space)) }) } pub fn all(&self, pred: |&T| -> bool) -> bool { @@ -353,9 +433,13 @@ impl VecPerParamSpace { } pub fn map(&self, pred: |&T| -> U) -> VecPerParamSpace { - VecPerParamSpace::new(self.vecs.ref0().iter().map(|p| pred(p)).collect(), - self.vecs.ref1().iter().map(|p| pred(p)).collect(), - self.vecs.ref2().iter().map(|p| pred(p)).collect()) + // FIXME (#15418): this could avoid allocating the intermediate + // Vec's, but note that the values of type_limit and self_limit + // also need to be kept in sync during construction. + VecPerParamSpace::new( + self.get_slice(TypeSpace).iter().map(|p| pred(p)).collect(), + self.get_slice(SelfSpace).iter().map(|p| pred(p)).collect(), + self.get_slice(FnSpace).iter().map(|p| pred(p)).collect()) } pub fn map_rev(&self, pred: |&T| -> U) -> VecPerParamSpace { @@ -368,29 +452,46 @@ impl VecPerParamSpace { * can be run to a fixed point */ - let mut fns: Vec = self.vecs.ref2().iter().rev().map(|p| pred(p)).collect(); + let mut fns: Vec = self.get_slice(FnSpace).iter().rev().map(|p| pred(p)).collect(); // NB: Calling foo.rev().map().rev() causes the calls to map // to occur in the wrong order. This was somewhat surprising // to me, though it makes total sense. fns.reverse(); - let mut selfs: Vec = self.vecs.ref1().iter().rev().map(|p| pred(p)).collect(); + let mut selfs: Vec = self.get_slice(SelfSpace).iter().rev().map(|p| pred(p)).collect(); selfs.reverse(); - let mut tys: Vec = self.vecs.ref0().iter().rev().map(|p| pred(p)).collect(); + let mut tys: Vec = self.get_slice(TypeSpace).iter().rev().map(|p| pred(p)).collect(); tys.reverse(); VecPerParamSpace::new(tys, selfs, fns) } pub fn split(self) -> (Vec, Vec, Vec) { - self.vecs + // FIXME (#15418): this does two traversals when in principle + // one would suffice. i.e. change to use `move_iter`. + let VecPerParamSpace { type_limit, self_limit, content } = self; + let mut i = 0; + let (prefix, fn_vec) = content.partition(|_| { + let on_left = i < self_limit; + i += 1; + on_left + }); + + let mut i = 0; + let (type_vec, self_vec) = prefix.partition(|_| { + let on_left = i < type_limit; + i += 1; + on_left + }); + + (type_vec, self_vec, fn_vec) } pub fn with_vec(mut self, space: ParamSpace, vec: Vec) -> VecPerParamSpace { - assert!(self.get_vec(space).is_empty()); - *self.get_mut_vec(space) = vec; + assert!(self.is_empty_in(space)); + self.replace(space, vec); self } } diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 0cc4a9223d499..dc9828606cc33 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -216,10 +216,8 @@ fn resolve_default_method_vtables(bcx: &Block, bcx.tcx(), ¶m_substs, &impl_res); // Now we pull any vtables for parameters on the actual method. - param_vtables - .get_mut_vec(subst::FnSpace) - .push_all( - impl_vtables.get_vec(subst::FnSpace).as_slice()); + param_vtables.push_all(subst::FnSpace, + impl_vtables.get_slice(subst::FnSpace)); param_vtables } diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index b3c7c0d0fac46..ddcc4c4bfa124 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -554,7 +554,7 @@ impl TypeMap { // Maybe check that there is no self type here. - let tps = substs.types.get_vec(subst::TypeSpace); + let tps = substs.types.get_slice(subst::TypeSpace); if tps.len() > 0 { output.push_char('<'); @@ -1377,9 +1377,9 @@ pub fn create_function_debug_context(cx: &CrateContext, } // Handle other generic parameters - let actual_types = param_substs.substs.types.get_vec(subst::FnSpace); + let actual_types = param_substs.substs.types.get_slice(subst::FnSpace); for (index, &ast::TyParam{ ident: ident, .. }) in generics.ty_params.iter().enumerate() { - let actual_type = *actual_types.get(index); + let actual_type = actual_types[index]; // Add actual type name to <...> clause of function name let actual_type_name = compute_debuginfo_type_name(cx, actual_type, diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index 31bf6cb0110a4..c26e11134b60a 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -209,7 +209,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type { // avoids creating more than one copy of the enum when one // of the enum's variants refers to the enum itself. let repr = adt::represent_type(cx, t); - let tps = substs.types.get_vec(subst::TypeSpace); + let tps = substs.types.get_slice(subst::TypeSpace); let name = llvm_type_name(cx, an_enum, did, tps); adt::incomplete_type_of(cx, &*repr, name.as_slice()) } @@ -266,7 +266,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type { // in *after* placing it into the type cache. This prevents // infinite recursion with recursive struct types. let repr = adt::represent_type(cx, t); - let tps = substs.types.get_vec(subst::TypeSpace); + let tps = substs.types.get_slice(subst::TypeSpace); let name = llvm_type_name(cx, a_struct, did, tps); adt::incomplete_type_of(cx, &*repr, name.as_slice()) } @@ -305,7 +305,7 @@ pub enum named_ty { a_struct, an_enum } pub fn llvm_type_name(cx: &CrateContext, what: named_ty, did: ast::DefId, - tps: &Vec) + tps: &[ty::t]) -> String { let name = match what { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 9629fb38af80f..141731ded9562 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -981,7 +981,7 @@ impl Generics { } pub fn has_type_params(&self, space: subst::ParamSpace) -> bool { - !self.types.get_vec(space).is_empty() + !self.types.is_empty_in(space) } } @@ -4644,14 +4644,14 @@ pub fn construct_parameter_environment( let mut types = VecPerParamSpace::empty(); for &space in subst::ParamSpace::all().iter() { push_types_from_defs(tcx, &mut types, space, - generics.types.get_vec(space)); + generics.types.get_slice(space)); } // map bound 'a => free 'a let mut regions = VecPerParamSpace::empty(); for &space in subst::ParamSpace::all().iter() { push_region_params(&mut regions, space, free_id, - generics.regions.get_vec(space)); + generics.regions.get_slice(space)); } let free_substs = Substs { @@ -4666,7 +4666,7 @@ pub fn construct_parameter_environment( let mut bounds = VecPerParamSpace::empty(); for &space in subst::ParamSpace::all().iter() { push_bounds_from_defs(tcx, &mut bounds, space, &free_substs, - generics.types.get_vec(space)); + generics.types.get_slice(space)); } debug!("construct_parameter_environment: free_id={} \ @@ -4684,7 +4684,7 @@ pub fn construct_parameter_environment( fn push_region_params(regions: &mut VecPerParamSpace, space: subst::ParamSpace, free_id: ast::NodeId, - region_params: &Vec) + region_params: &[RegionParameterDef]) { for r in region_params.iter() { regions.push(space, ty::free_region_from_def(free_id, r)); @@ -4694,7 +4694,7 @@ pub fn construct_parameter_environment( fn push_types_from_defs(tcx: &ty::ctxt, types: &mut subst::VecPerParamSpace, space: subst::ParamSpace, - defs: &Vec) { + defs: &[TypeParameterDef]) { for (i, def) in defs.iter().enumerate() { let ty = ty::mk_param(tcx, space, i, def.def_id); types.push(space, ty); @@ -4705,7 +4705,7 @@ pub fn construct_parameter_environment( bounds: &mut subst::VecPerParamSpace, space: subst::ParamSpace, free_substs: &subst::Substs, - defs: &Vec) { + defs: &[TypeParameterDef]) { for def in defs.iter() { let b = (*def.bounds).subst(tcx, free_substs); bounds.push(space, b); diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 1ad15e536ecc4..286cb5364758a 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -203,7 +203,7 @@ fn ast_path_substs( }; // Convert the type parameters supplied by the user. - let ty_param_defs = decl_generics.types.get_vec(TypeSpace); + let ty_param_defs = decl_generics.types.get_slice(TypeSpace); let supplied_ty_param_count = path.segments.iter().flat_map(|s| s.types.iter()).count(); let formal_ty_param_count = ty_param_defs.len(); let required_ty_param_count = ty_param_defs.iter() diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index c3b2756bdbff2..6e44665fb3b46 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -264,7 +264,7 @@ fn construct_transformed_self_ty_for_object( // The subst we get in has Err as the "Self" type. For an object // type, we don't put any type into the Self paramspace, so let's // make a copy of rcvr_substs that has the Self paramspace empty. - obj_substs.types.get_mut_vec(subst::SelfSpace).pop().unwrap(); + obj_substs.types.pop(subst::SelfSpace).unwrap(); match method_ty.explicit_self { ast::SelfStatic => { @@ -1133,7 +1133,7 @@ impl<'a> LookupContext<'a> { let m_regions = self.fcx.infcx().region_vars_for_defs( self.span, - candidate.method_ty.generics.regions.get_vec(subst::FnSpace)); + candidate.method_ty.generics.regions.get_slice(subst::FnSpace)); let all_substs = candidate.rcvr_substs.clone().with_method(m_types, m_regions); diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index b68991aed7096..e4d9bcfad61ce 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -917,8 +917,8 @@ fn compare_impl_method(tcx: &ty::ctxt, return; } - let it = trait_m.generics.types.get_vec(subst::FnSpace).iter() - .zip(impl_m.generics.types.get_vec(subst::FnSpace).iter()); + let it = trait_m.generics.types.get_slice(subst::FnSpace).iter() + .zip(impl_m.generics.types.get_slice(subst::FnSpace).iter()); // This code is best explained by example. Consider a trait: // @@ -989,8 +989,8 @@ fn compare_impl_method(tcx: &ty::ctxt, let trait_to_skol_substs = trait_to_impl_substs .subst(tcx, &impl_to_skol_substs) - .with_method(skol_tps.get_vec(subst::FnSpace).clone(), - skol_regions.get_vec(subst::FnSpace).clone()); + .with_method(Vec::from_slice(skol_tps.get_slice(subst::FnSpace)), + Vec::from_slice(skol_regions.get_slice(subst::FnSpace))); let trait_fty = ty::mk_bare_fn(tcx, trait_m.fty.clone()); let trait_fty = trait_fty.subst(tcx, &trait_to_skol_substs); @@ -2002,7 +2002,7 @@ pub fn impl_self_ty(vcx: &VtableContext, let ity = ty::lookup_item_type(tcx, did); let (n_tps, rps, raw_ty) = (ity.generics.types.len(subst::TypeSpace), - ity.generics.regions.get_vec(subst::TypeSpace), + ity.generics.regions.get_slice(subst::TypeSpace), ity.ty); let rps = vcx.infcx.region_vars_for_defs(span, rps); @@ -4126,12 +4126,10 @@ pub fn instantiate_path(fcx: &FnCtxt, // a problem. for &space in ParamSpace::all().iter() { adjust_type_parameters(fcx, span, space, type_defs, &mut substs); - assert_eq!(substs.types.get_vec(space).len(), - type_defs.get_vec(space).len()); + assert_eq!(substs.types.len(space), type_defs.len(space)); adjust_region_parameters(fcx, span, space, region_defs, &mut substs); - assert_eq!(substs.regions().get_vec(space).len(), - region_defs.get_vec(space).len()); + assert_eq!(substs.regions().len(space), region_defs.len(space)); } fcx.write_ty_substs(node_id, polytype.ty, ty::ItemSubsts { @@ -4183,8 +4181,8 @@ pub fn instantiate_path(fcx: &FnCtxt, */ { - let type_count = type_defs.get_vec(space).len(); - assert_eq!(substs.types.get_vec(space).len(), 0); + let type_count = type_defs.len(space); + assert_eq!(substs.types.len(space), 0); for (i, &typ) in segment.types.iter().enumerate() { let t = fcx.to_ty(&*typ); if i < type_count { @@ -4198,14 +4196,14 @@ pub fn instantiate_path(fcx: &FnCtxt, but found {} parameter(s)", type_count, segment.types.len()).as_slice()); - substs.types.get_mut_vec(space).truncate(0); + substs.types.truncate(space, 0); } } } { - let region_count = region_defs.get_vec(space).len(); - assert_eq!(substs.regions().get_vec(space).len(), 0); + let region_count = region_defs.len(space); + assert_eq!(substs.regions().len(space), 0); for (i, lifetime) in segment.lifetimes.iter().enumerate() { let r = ast_region_to_region(fcx.tcx(), lifetime); if i < region_count { @@ -4218,7 +4216,7 @@ pub fn instantiate_path(fcx: &FnCtxt, expected {} parameter(s) but found {} parameter(s)", region_count, segment.lifetimes.len()).as_slice()); - substs.mut_regions().get_mut_vec(space).truncate(0); + substs.mut_regions().truncate(space, 0); } } } @@ -4231,8 +4229,8 @@ pub fn instantiate_path(fcx: &FnCtxt, defs: &VecPerParamSpace, substs: &mut Substs) { - let provided_len = substs.types.get_vec(space).len(); - let desired = defs.get_vec(space).as_slice(); + let provided_len = substs.types.len(space); + let desired = defs.get_slice(space); let required_len = desired.iter() .take_while(|d| d.default.is_none()) .count(); @@ -4252,8 +4250,8 @@ pub fn instantiate_path(fcx: &FnCtxt, // Nothing specified at all: supply inference variables for // everything. if provided_len == 0 { - let provided = substs.types.get_mut_vec(space); - *provided = fcx.infcx().next_ty_vars(desired.len()); + substs.types.replace(space, + fcx.infcx().next_ty_vars(desired.len())); return; } @@ -4270,8 +4268,8 @@ pub fn instantiate_path(fcx: &FnCtxt, qualifier, required_len, provided_len).as_slice()); - let provided = substs.types.get_mut_vec(space); - *provided = Vec::from_elem(desired.len(), ty::mk_err()); + substs.types.replace(space, + Vec::from_elem(desired.len(), ty::mk_err())); return; } @@ -4287,7 +4285,7 @@ pub fn instantiate_path(fcx: &FnCtxt, let default = default.subst_spanned(fcx.tcx(), substs, Some(span)); substs.types.push(space, default); } - assert_eq!(substs.types.get_vec(space).len(), desired.len()); + assert_eq!(substs.types.len(space), desired.len()); debug!("Final substs: {}", substs.repr(fcx.tcx())); } @@ -4299,20 +4297,22 @@ pub fn instantiate_path(fcx: &FnCtxt, defs: &VecPerParamSpace, substs: &mut Substs) { - let provided = substs.mut_regions().get_mut_vec(space); - let desired = defs.get_vec(space); + let provided_len = substs.mut_regions().len(space); + let desired = defs.get_slice(space); // Enforced by `push_explicit_parameters_from_segment_to_substs()`. - assert!(provided.len() <= desired.len()); + assert!(provided_len <= desired.len()); // If nothing was provided, just use inference variables. - if provided.len() == 0 { - *provided = fcx.infcx().region_vars_for_defs(span, desired); + if provided_len == 0 { + substs.mut_regions().replace( + space, + fcx.infcx().region_vars_for_defs(span, desired)); return; } // If just the right number were provided, everybody is happy. - if provided.len() == desired.len() { + if provided_len == desired.len() { return; } @@ -4325,9 +4325,11 @@ pub fn instantiate_path(fcx: &FnCtxt, expected {} parameter(s) \ but found {} parameter(s)", desired.len(), - provided.len()).as_slice()); + provided_len).as_slice()); - *provided = fcx.infcx().region_vars_for_defs(span, desired); + substs.mut_regions().replace( + space, + fcx.infcx().region_vars_for_defs(span, desired)); } } diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index 32e34d1320eb5..b9bf8e37dead8 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -735,12 +735,12 @@ pub fn make_substs_for_receiver_types(tcx: &ty::ctxt, */ let meth_tps: Vec = - method.generics.types.get_vec(subst::FnSpace) + method.generics.types.get_slice(subst::FnSpace) .iter() .map(|def| ty::mk_param_from_def(tcx, def)) .collect(); let meth_regions: Vec = - method.generics.regions.get_vec(subst::FnSpace) + method.generics.regions.get_slice(subst::FnSpace) .iter() .map(|def| ty::ReEarlyBound(def.def_id.node, def.space, def.index, def.name)) @@ -767,10 +767,12 @@ fn subst_receiver_types_in_method_ty(tcx: &ty::ctxt, // replace the type parameters declared on the trait with those // from the impl for &space in [subst::TypeSpace, subst::SelfSpace].iter() { - *method_generics.types.get_mut_vec(space) = - impl_poly_type.generics.types.get_vec(space).clone(); - *method_generics.regions.get_mut_vec(space) = - impl_poly_type.generics.regions.get_vec(space).clone(); + method_generics.types.replace( + space, + Vec::from_slice(impl_poly_type.generics.types.get_slice(space))); + method_generics.regions.replace( + space, + Vec::from_slice(impl_poly_type.generics.regions.get_slice(space))); } debug!("subst_receiver_types_in_method_ty: method_generics={}", diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index 2984ea086efc5..1e33b1d5d0ebd 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -115,32 +115,30 @@ pub trait Combine { let mut substs = subst::Substs::empty(); for &space in subst::ParamSpace::all().iter() { - let a_tps = a_subst.types.get_vec(space); - let b_tps = b_subst.types.get_vec(space); - let tps = if_ok!(self.tps(space, - a_tps.as_slice(), - b_tps.as_slice())); - - let a_regions = a_subst.regions().get_vec(space); - let b_regions = b_subst.regions().get_vec(space); - let r_variances = variances.regions.get_vec(space); + let a_tps = a_subst.types.get_slice(space); + let b_tps = b_subst.types.get_slice(space); + let tps = if_ok!(self.tps(space, a_tps, b_tps)); + + let a_regions = a_subst.regions().get_slice(space); + let b_regions = b_subst.regions().get_slice(space); + let r_variances = variances.regions.get_slice(space); let regions = if_ok!(relate_region_params(self, item_def_id, r_variances, a_regions, b_regions)); - *substs.types.get_mut_vec(space) = tps; - *substs.mut_regions().get_mut_vec(space) = regions; + substs.types.replace(space, tps); + substs.mut_regions().replace(space, regions); } return Ok(substs); fn relate_region_params(this: &C, item_def_id: ast::DefId, - variances: &Vec, - a_rs: &Vec, - b_rs: &Vec) + variances: &[ty::Variance], + a_rs: &[ty::Region], + b_rs: &[ty::Region]) -> cres> { let tcx = this.infcx().tcx; @@ -160,9 +158,9 @@ pub trait Combine { assert_eq!(num_region_params, b_rs.len()); let mut rs = vec!(); for i in range(0, num_region_params) { - let a_r = *a_rs.get(i); - let b_r = *b_rs.get(i); - let variance = *variances.get(i); + let a_r = a_rs[i]; + let b_r = b_rs[i]; + let variance = variances[i]; let r = match variance { ty::Invariant => { eq_regions(this, a_r, b_r) diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index bc02297b5b1f3..b505536a59db2 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -624,7 +624,7 @@ impl<'a> InferCtxt<'a> { pub fn region_vars_for_defs(&self, span: Span, - defs: &Vec) + defs: &[ty::RegionParameterDef]) -> Vec { defs.iter() .map(|d| self.next_region_var(EarlyBoundRegion(span, d.name))) @@ -647,7 +647,7 @@ impl<'a> InferCtxt<'a> { assert!(generics.regions.len(subst::FnSpace) == 0); let type_parameter_count = generics.types.len(subst::TypeSpace); - let region_param_defs = generics.regions.get_vec(subst::TypeSpace); + let region_param_defs = generics.regions.get_slice(subst::TypeSpace); let regions = self.region_vars_for_defs(span, region_param_defs); let type_parameters = self.next_ty_vars(type_parameter_count); subst::Substs::new_type(type_parameters, regions) diff --git a/src/librustc/middle/typeck/variance.rs b/src/librustc/middle/typeck/variance.rs index 0a60a5ce0e9fa..fb3ce391d8e34 100644 --- a/src/librustc/middle/typeck/variance.rs +++ b/src/librustc/middle/typeck/variance.rs @@ -749,15 +749,15 @@ impl<'a> ConstraintContext<'a> { // All type parameters on enums and structs should be // in the TypeSpace. - assert!(generics.types.get_vec(subst::SelfSpace).is_empty()); - assert!(generics.types.get_vec(subst::FnSpace).is_empty()); - assert!(generics.regions.get_vec(subst::SelfSpace).is_empty()); - assert!(generics.regions.get_vec(subst::FnSpace).is_empty()); + assert!(generics.types.is_empty_in(subst::SelfSpace)); + assert!(generics.types.is_empty_in(subst::FnSpace)); + assert!(generics.regions.is_empty_in(subst::SelfSpace)); + assert!(generics.regions.is_empty_in(subst::FnSpace)); self.add_constraints_from_substs( def_id, - generics.types.get_vec(subst::TypeSpace), - generics.regions.get_vec(subst::TypeSpace), + generics.types.get_slice(subst::TypeSpace), + generics.regions.get_slice(subst::TypeSpace), substs, variance); } @@ -768,22 +768,22 @@ impl<'a> ConstraintContext<'a> { // Traits DO have a Self type parameter, but it is // erased from object types. - assert!(!generics.types.get_vec(subst::SelfSpace).is_empty() && - substs.types.get_vec(subst::SelfSpace).is_empty()); + assert!(!generics.types.is_empty_in(subst::SelfSpace) && + substs.types.is_empty_in(subst::SelfSpace)); // Traits never declare region parameters in the self // space. - assert!(generics.regions.get_vec(subst::SelfSpace).is_empty()); + assert!(generics.regions.is_empty_in(subst::SelfSpace)); // Traits never declare type/region parameters in the // fn space. - assert!(generics.types.get_vec(subst::FnSpace).is_empty()); - assert!(generics.regions.get_vec(subst::FnSpace).is_empty()); + assert!(generics.types.is_empty_in(subst::FnSpace)); + assert!(generics.regions.is_empty_in(subst::FnSpace)); self.add_constraints_from_substs( def_id, - generics.types.get_vec(subst::TypeSpace), - generics.regions.get_vec(subst::TypeSpace), + generics.types.get_slice(subst::TypeSpace), + generics.regions.get_slice(subst::TypeSpace), substs, variance); } @@ -832,8 +832,8 @@ impl<'a> ConstraintContext<'a> { /// object, etc) appearing in a context with ambient variance `variance` fn add_constraints_from_substs(&mut self, def_id: ast::DefId, - type_param_defs: &Vec, - region_param_defs: &Vec, + type_param_defs: &[ty::TypeParameterDef], + region_param_defs: &[ty::RegionParameterDef], substs: &subst::Substs, variance: VarianceTermPtr<'a>) { debug!("add_constraints_from_substs(def_id={:?})", def_id); diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index fa353652fe1ec..85edd4ea481ae 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -449,8 +449,8 @@ pub fn parameterized(cx: &ctxt, } } - let tps = substs.types.get_vec(subst::TypeSpace); - let ty_params = generics.types.get_vec(subst::TypeSpace); + let tps = substs.types.get_slice(subst::TypeSpace); + let ty_params = generics.types.get_slice(subst::TypeSpace); let has_defaults = ty_params.last().map_or(false, |def| def.default.is_some()); let num_defaults = if has_defaults && !cx.sess.verbose() { ty_params.iter().zip(tps.iter()).rev().take_while(|&(def, &actual)| { @@ -468,7 +468,7 @@ pub fn parameterized(cx: &ctxt, } if cx.sess.verbose() { - for t in substs.types.get_vec(subst::SelfSpace).iter() { + for t in substs.types.get_slice(subst::SelfSpace).iter() { strs.push(format!("for {}", t.repr(cx))); } } @@ -598,9 +598,9 @@ impl Repr for subst::Substs { impl Repr for subst::VecPerParamSpace { fn repr(&self, tcx: &ctxt) -> String { format!("[{};{};{}]", - self.get_vec(subst::TypeSpace).repr(tcx), - self.get_vec(subst::SelfSpace).repr(tcx), - self.get_vec(subst::FnSpace).repr(tcx)) + self.get_slice(subst::TypeSpace).repr(tcx), + self.get_slice(subst::SelfSpace).repr(tcx), + self.get_slice(subst::FnSpace).repr(tcx)) } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 4808cbdb4b09b..12c183132d622 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -505,11 +505,12 @@ impl Clean for ast::TyParamBound { } fn external_path(name: &str, substs: &subst::Substs) -> Path { - let lifetimes = substs.regions().get_vec(subst::TypeSpace) + let lifetimes = substs.regions().get_slice(subst::TypeSpace) .iter() .filter_map(|v| v.clean()) .collect(); - let types = substs.types.get_vec(subst::TypeSpace).clean(); + let types = Vec::from_slice(substs.types.get_slice(subst::TypeSpace)); + let types = types.clean(); Path { global: false, segments: vec![PathSegment { @@ -674,8 +675,8 @@ impl Clean for ty::Generics { // is implicit. let space = { - if !self.types.get_vec(subst::FnSpace).is_empty() || - !self.regions.get_vec(subst::FnSpace).is_empty() + if !self.types.is_empty_in(subst::FnSpace) || + !self.regions.is_empty_in(subst::FnSpace) { subst::FnSpace } else { @@ -684,8 +685,8 @@ impl Clean for ty::Generics { }; Generics { - type_params: self.types.get_vec(space).clean(), - lifetimes: self.regions.get_vec(space).clean(), + type_params: Vec::from_slice(self.types.get_slice(space)).clean(), + lifetimes: Vec::from_slice(self.regions.get_slice(space)).clean(), } } }