diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs index 500255db330c..bea9bbad1ac0 100644 --- a/src/librustc/middle/subst.rs +++ b/src/librustc/middle/subst.rs @@ -448,20 +448,6 @@ impl VecPerParamSpace { self.self_limit) } - pub fn map_move(self, mut pred: F) -> VecPerParamSpace where - F: FnMut(T) -> U, - { - let SeparateVecsPerParamSpace { - types: t, - selfs: s, - fns: f - } = self.split(); - - VecPerParamSpace::new(t.into_iter().map(|p| pred(p)).collect(), - s.into_iter().map(|p| pred(p)).collect(), - f.into_iter().map(|p| pred(p)).collect()) - } - pub fn split(self) -> SeparateVecsPerParamSpace { let VecPerParamSpace { type_limit, self_limit, content } = self; diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs index 5938c6df92a6..b51fc90acf27 100644 --- a/src/librustc/middle/traits/fulfill.rs +++ b/src/librustc/middle/traits/fulfill.rs @@ -329,7 +329,7 @@ fn process_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>, false } Ok(Some(s)) => { - s.map_move_nested(|p| new_obligations.push(p)); + new_obligations.append(&mut s.nested_obligations()); true } Err(selection_err) => { diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index fe61bb5e4ea6..b371ede0397e 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -20,7 +20,6 @@ use middle::subst; use middle::ty::{self, HasProjectionTypes, Ty}; use middle::ty_fold::TypeFoldable; use middle::infer::{self, fixup_err_to_string, InferCtxt}; -use std::slice::Iter; use std::rc::Rc; use syntax::ast; use syntax::codemap::{Span, DUMMY_SP}; @@ -146,9 +145,9 @@ pub struct DerivedObligationCause<'tcx> { parent_code: Rc> } -pub type Obligations<'tcx, O> = subst::VecPerParamSpace>; -pub type PredicateObligations<'tcx> = subst::VecPerParamSpace>; -pub type TraitObligations<'tcx> = subst::VecPerParamSpace>; +pub type Obligations<'tcx, O> = Vec>; +pub type PredicateObligations<'tcx> = Vec>; +pub type TraitObligations<'tcx> = Vec>; pub type Selection<'tcx> = Vtable<'tcx, PredicateObligation<'tcx>>; @@ -266,7 +265,7 @@ pub enum Vtable<'tcx, N> { pub struct VtableImplData<'tcx, N> { pub impl_def_id: ast::DefId, pub substs: subst::Substs<'tcx>, - pub nested: subst::VecPerParamSpace + pub nested: Vec } #[derive(Debug,Clone)] @@ -277,7 +276,7 @@ pub struct VtableDefaultImplData { #[derive(Debug,Clone)] pub struct VtableBuiltinData { - pub nested: subst::VecPerParamSpace + pub nested: Vec } /// A vtable for some object-safe trait `Foo` automatically derived @@ -525,114 +524,35 @@ impl<'tcx> ObligationCause<'tcx> { } impl<'tcx, N> Vtable<'tcx, N> { - pub fn iter_nested(&self) -> Iter { - match *self { - VtableImpl(ref i) => i.iter_nested(), - VtableParam(ref n) => n.iter(), - VtableBuiltin(ref i) => i.iter_nested(), - VtableObject(_) | - VtableDefaultImpl(..) | VtableFnPointer(..) | - VtableClosure(..) => (&[]).iter(), - } - } - - pub fn map_nested(&self, op: F) -> Vtable<'tcx, M> where - F: FnMut(&N) -> M, - { - match *self { - VtableImpl(ref i) => VtableImpl(i.map_nested(op)), - VtableDefaultImpl(ref t) => VtableDefaultImpl(t.map_nested(op)), - VtableFnPointer(ref sig) => VtableFnPointer((*sig).clone()), - VtableClosure(d, ref s) => VtableClosure(d, s.clone()), - VtableParam(ref n) => VtableParam(n.iter().map(op).collect()), - VtableObject(ref p) => VtableObject(p.clone()), - VtableBuiltin(ref b) => VtableBuiltin(b.map_nested(op)), + pub fn nested_obligations(self) -> Vec { + match self { + VtableImpl(i) => i.nested, + VtableParam(n) => n, + VtableBuiltin(i) => i.nested, + VtableDefaultImpl(d) => d.nested, + VtableObject(_) | VtableFnPointer(..) | + VtableClosure(..) => vec![] } } - pub fn map_move_nested(self, op: F) -> Vtable<'tcx, M> where - F: FnMut(N) -> M, - { + pub fn map(self, f: F) -> Vtable<'tcx, M> where F: FnMut(N) -> M { match self { - VtableImpl(i) => VtableImpl(i.map_move_nested(op)), - VtableFnPointer(sig) => VtableFnPointer(sig), + VtableImpl(i) => VtableImpl(VtableImplData { + impl_def_id: i.impl_def_id, + substs: i.substs, + nested: i.nested.into_iter().map(f).collect() + }), + VtableParam(n) => VtableParam(n.into_iter().map(f).collect()), + VtableBuiltin(i) => VtableBuiltin(VtableBuiltinData { + nested: i.nested.into_iter().map(f).collect() + }), + VtableObject(o) => VtableObject(o), + VtableDefaultImpl(d) => VtableDefaultImpl(VtableDefaultImplData { + trait_def_id: d.trait_def_id, + nested: d.nested.into_iter().map(f).collect() + }), + VtableFnPointer(f) => VtableFnPointer(f), VtableClosure(d, s) => VtableClosure(d, s), - VtableDefaultImpl(t) => VtableDefaultImpl(t.map_move_nested(op)), - VtableParam(n) => VtableParam(n.into_iter().map(op).collect()), - VtableObject(p) => VtableObject(p), - VtableBuiltin(no) => VtableBuiltin(no.map_move_nested(op)), - } - } -} - -impl<'tcx, N> VtableImplData<'tcx, N> { - pub fn iter_nested(&self) -> Iter { - self.nested.iter() - } - - pub fn map_nested(&self, op: F) -> VtableImplData<'tcx, M> where - F: FnMut(&N) -> M, - { - VtableImplData { - impl_def_id: self.impl_def_id, - substs: self.substs.clone(), - nested: self.nested.map(op) - } - } - - pub fn map_move_nested(self, op: F) -> VtableImplData<'tcx, M> where - F: FnMut(N) -> M, - { - let VtableImplData { impl_def_id, substs, nested } = self; - VtableImplData { - impl_def_id: impl_def_id, - substs: substs, - nested: nested.map_move(op) - } - } -} - -impl VtableDefaultImplData { - pub fn iter_nested(&self) -> Iter { - self.nested.iter() - } - - pub fn map_nested(&self, op: F) -> VtableDefaultImplData where - F: FnMut(&N) -> M, - { - VtableDefaultImplData { - trait_def_id: self.trait_def_id, - nested: self.nested.iter().map(op).collect() - } - } - - pub fn map_move_nested(self, op: F) -> VtableDefaultImplData where - F: FnMut(N) -> M, - { - let VtableDefaultImplData { trait_def_id, nested } = self; - VtableDefaultImplData { - trait_def_id: trait_def_id, - nested: nested.into_iter().map(op).collect() - } - } -} - -impl VtableBuiltinData { - pub fn iter_nested(&self) -> Iter { - self.nested.iter() - } - - pub fn map_nested(&self, op: F) -> VtableBuiltinData where F: FnMut(&N) -> M { - VtableBuiltinData { - nested: self.nested.map(op) - } - } - - pub fn map_move_nested(self, op: F) -> VtableBuiltinData where - F: FnMut(N) -> M, - { - VtableBuiltinData { - nested: self.nested.map_move(op) } } } diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs index 969f82cc5ae1..cf641403ddc5 100644 --- a/src/librustc/middle/traits/project.rs +++ b/src/librustc/middle/traits/project.rs @@ -203,6 +203,7 @@ pub fn normalize_with_depth<'a,'b,'tcx,T>(selcx: &'a mut SelectionContext<'b,'tc { let mut normalizer = AssociatedTypeNormalizer::new(selcx, cause, depth); let result = normalizer.fold(value); + Normalized { value: result, obligations: normalizer.obligations, @@ -864,7 +865,7 @@ fn confirm_impl_candidate<'cx,'tcx>( if let ty::TypeTraitItem(ref assoc_ty) = impl_or_trait_items_map[&impl_item.def_id()] { if assoc_ty.name == obligation.predicate.item_name { return (assoc_ty.ty.unwrap().subst(selcx.tcx(), &impl_vtable.substs), - impl_vtable.nested.into_vec()); + impl_vtable.nested); } } } @@ -876,7 +877,7 @@ fn confirm_impl_candidate<'cx,'tcx>( if assoc_ty.name == obligation.predicate.item_name { if let Some(ty) = assoc_ty.ty { return (ty.subst(selcx.tcx(), trait_ref.substs), - impl_vtable.nested.into_vec()); + impl_vtable.nested); } else { // This means that the impl is missing a // definition for the associated type. This error diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 8011d2962631..b568d40ba1c9 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -36,7 +36,7 @@ use super::object_safety; use super::util; use middle::fast_reject; -use middle::subst::{Subst, Substs, TypeSpace, VecPerParamSpace}; +use middle::subst::{Subst, Substs, TypeSpace}; use middle::ty::{self, AsPredicate, RegionEscape, ToPolyTraitRef, Ty}; use middle::infer; use middle::infer::{InferCtxt, TypeFreshener}; @@ -1134,7 +1134,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // type/region parameters let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder()); let (closure_def_id, substs) = match self_ty.sty { - ty::ty_closure(id, ref substs) => (id, substs.clone()), + ty::ty_closure(id, substs) => (id, substs), ty::ty_infer(ty::TyVar(_)) => { debug!("assemble_unboxed_closure_candidates: ambiguous self-type"); candidates.ambiguous = true; @@ -1152,7 +1152,8 @@ 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.clone())); + candidates.vec.push(ClosureCandidate(closure_def_id, + substs.clone())); } } None => { @@ -1479,7 +1480,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { selection: Selection<'tcx>) -> EvaluationResult<'tcx> { - self.evaluate_predicates_recursively(stack, selection.iter_nested()) + self.evaluate_predicates_recursively(stack, + selection.nested_obligations().iter()) } /// Returns true if `candidate_i` should be dropped in favor of @@ -1987,7 +1989,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { PhantomFnCandidate | ErrorCandidate => { - Ok(VtableBuiltin(VtableBuiltinData { nested: VecPerParamSpace::empty() })) + Ok(VtableBuiltin(VtableBuiltinData { nested: vec![] })) } ParamCandidate(param) => { @@ -2120,8 +2122,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let obligations = self.collect_predicates_for_types(obligation, trait_def, nested); - let obligations = VecPerParamSpace::new(obligations, Vec::new(), Vec::new()); - debug!("vtable_builtin_data: obligations={}", obligations.repr(self.tcx())); @@ -2207,7 +2207,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { trait_def_id, nested); - let trait_obligations: Result,()> = self.infcx.commit_if_ok(|snapshot| { + let trait_obligations: Result,()> = self.infcx.commit_if_ok(|snapshot| { let poly_trait_ref = obligation.predicate.to_poly_trait_ref(); let (trait_ref, skol_map) = self.infcx().skolemize_late_bound_regions(&poly_trait_ref, snapshot); @@ -2219,7 +2219,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { snapshot)) }); - obligations.extend(trait_obligations.unwrap().into_iter()); // no Errors in that code above + // no Errors in that code above + obligations.append(&mut trait_obligations.unwrap()); debug!("vtable_default_impl_data: obligations={}", obligations.repr(self.tcx())); @@ -2253,7 +2254,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn vtable_impl(&mut self, impl_def_id: ast::DefId, - substs: Normalized<'tcx, Substs<'tcx>>, + mut substs: Normalized<'tcx, Substs<'tcx>>, cause: ObligationCause<'tcx>, recursion_depth: usize, skol_map: infer::SkolemizationMap, @@ -2278,7 +2279,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { impl_def_id.repr(self.tcx()), impl_obligations.repr(self.tcx())); - impl_obligations.extend(TypeSpace, substs.obligations.into_iter()); + impl_obligations.append(&mut substs.obligations); VtableImplData { impl_def_id: impl_def_id, substs: substs.value, @@ -2568,9 +2569,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { _ => unreachable!() }; - Ok(VtableBuiltinData { - nested: VecPerParamSpace::new(nested, vec![], vec![]) - }) + Ok(VtableBuiltinData { nested: nested }) } /////////////////////////////////////////////////////////////////////////// @@ -2851,20 +2850,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { substs: &Substs<'tcx>, // for impl or trait skol_map: infer::SkolemizationMap, snapshot: &infer::CombinedSnapshot) - -> VecPerParamSpace> + -> Vec> { debug!("impl_or_trait_obligations(def_id={})", def_id.repr(self.tcx())); let predicates = ty::lookup_predicates(self.tcx(), def_id); let predicates = predicates.instantiate(self.tcx(), substs); let predicates = normalize_with_depth(self, cause.clone(), recursion_depth, &predicates); - let predicates = self.infcx().plug_leaks(skol_map, snapshot, &predicates); + let mut predicates = self.infcx().plug_leaks(skol_map, snapshot, &predicates); let mut obligations = util::predicates_for_generics(self.tcx(), cause, recursion_depth, &predicates.value); - obligations.extend(TypeSpace, predicates.obligations.into_iter()); + obligations.append(&mut predicates.obligations); obligations } diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs index f30f8560b9fe..ffa14feee47f 100644 --- a/src/librustc/middle/traits/util.rs +++ b/src/librustc/middle/traits/util.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use middle::subst::{Substs, VecPerParamSpace}; +use middle::subst::Substs; use middle::infer::InferCtxt; use middle::ty::{self, Ty, AsPredicate, ToPolyTraitRef}; use std::fmt; @@ -319,16 +319,16 @@ pub fn predicates_for_generics<'tcx>(tcx: &ty::ctxt<'tcx>, cause: ObligationCause<'tcx>, recursion_depth: usize, generic_bounds: &ty::InstantiatedPredicates<'tcx>) - -> VecPerParamSpace> + -> Vec> { debug!("predicates_for_generics(generic_bounds={})", generic_bounds.repr(tcx)); - generic_bounds.predicates.map(|predicate| { + generic_bounds.predicates.iter().map(|predicate| { Obligation { cause: cause.clone(), recursion_depth: recursion_depth, predicate: predicate.clone() } - }) + }).collect() } pub fn trait_ref_for_builtin_bound<'tcx>( diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 758702f54c04..579199aba08c 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -1051,7 +1051,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // all nested obligations. This is because they can inform the // inference of the impl's type parameters. let mut fulfill_cx = traits::FulfillmentContext::new(); - let vtable = selection.map_move_nested(|predicate| { + let vtable = selection.map(|predicate| { fulfill_cx.register_predicate_obligation(&infcx, predicate); }); let vtable = drain_fulfillment_cx_or_panic(span, &infcx, &mut fulfill_cx, &vtable); diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index dd63a512ae39..92317aae0896 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -323,7 +323,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { } Ok(Some(vtable)) => { - vtable.map_move_nested(|o| queue.push_back(o)); + for obligation in vtable.nested_obligations() { + queue.push_back(obligation); + } } } } diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 2eca855d5960..1bef5cb19db1 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -1046,7 +1046,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { debug!("impl_obligations={}", obligations.repr(self.tcx())); // Evaluate those obligations to see if they might possibly hold. - obligations.all(|o| selcx.evaluate_obligation(o)) && + obligations.iter().all(|o| selcx.evaluate_obligation(o)) && norm_obligations.iter().all(|o| selcx.evaluate_obligation(o)) } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e7e8140aab31..e37856bbb2ea 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1788,11 +1788,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("add_obligations_for_parameters(predicates={})", predicates.repr(self.tcx())); - let obligations = traits::predicates_for_generics(self.tcx(), + for obligation in traits::predicates_for_generics(self.tcx(), cause, - predicates); - - obligations.map_move(|o| self.register_predicate(o)); + predicates) { + self.register_predicate(obligation); + } } // Only for fields! Returns for methods>