Skip to content

Commit

Permalink
Use a plain Vec instead of VecPerParamSpace in trait selection.
Browse files Browse the repository at this point in the history
  • Loading branch information
arielb1 committed Jun 3, 2015
1 parent 9c30394 commit 4b116fe
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 154 deletions.
14 changes: 0 additions & 14 deletions src/librustc/middle/subst.rs
Expand Up @@ -448,20 +448,6 @@ impl<T> VecPerParamSpace<T> {
self.self_limit)
}

pub fn map_move<U, F>(self, mut pred: F) -> VecPerParamSpace<U> 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<T> {
let VecPerParamSpace { type_limit, self_limit, content } = self;

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/traits/fulfill.rs
Expand Up @@ -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) => {
Expand Down
138 changes: 29 additions & 109 deletions src/librustc/middle/traits/mod.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -146,9 +145,9 @@ pub struct DerivedObligationCause<'tcx> {
parent_code: Rc<ObligationCauseCode<'tcx>>
}

pub type Obligations<'tcx, O> = subst::VecPerParamSpace<Obligation<'tcx, O>>;
pub type PredicateObligations<'tcx> = subst::VecPerParamSpace<PredicateObligation<'tcx>>;
pub type TraitObligations<'tcx> = subst::VecPerParamSpace<TraitObligation<'tcx>>;
pub type Obligations<'tcx, O> = Vec<Obligation<'tcx, O>>;
pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
pub type TraitObligations<'tcx> = Vec<TraitObligation<'tcx>>;

pub type Selection<'tcx> = Vtable<'tcx, PredicateObligation<'tcx>>;

Expand Down Expand Up @@ -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<N>
pub nested: Vec<N>
}

#[derive(Debug,Clone)]
Expand All @@ -277,7 +276,7 @@ pub struct VtableDefaultImplData<N> {

#[derive(Debug,Clone)]
pub struct VtableBuiltinData<N> {
pub nested: subst::VecPerParamSpace<N>
pub nested: Vec<N>
}

/// A vtable for some object-safe trait `Foo` automatically derived
Expand Down Expand Up @@ -525,114 +524,35 @@ impl<'tcx> ObligationCause<'tcx> {
}

impl<'tcx, N> Vtable<'tcx, N> {
pub fn iter_nested(&self) -> Iter<N> {
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<M, F>(&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<N> {
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<M, F>(self, op: F) -> Vtable<'tcx, M> where
F: FnMut(N) -> M,
{
pub fn map<M, F>(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<N> {
self.nested.iter()
}

pub fn map_nested<M, F>(&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<M, F>(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<N> VtableDefaultImplData<N> {
pub fn iter_nested(&self) -> Iter<N> {
self.nested.iter()
}

pub fn map_nested<M, F>(&self, op: F) -> VtableDefaultImplData<M> 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<M, F>(self, op: F) -> VtableDefaultImplData<M> 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<N> VtableBuiltinData<N> {
pub fn iter_nested(&self) -> Iter<N> {
self.nested.iter()
}

pub fn map_nested<M, F>(&self, op: F) -> VtableBuiltinData<M> where F: FnMut(&N) -> M {
VtableBuiltinData {
nested: self.nested.map(op)
}
}

pub fn map_move_nested<M, F>(self, op: F) -> VtableBuiltinData<M> where
F: FnMut(N) -> M,
{
VtableBuiltinData {
nested: self.nested.map_move(op)
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/librustc/middle/traits/project.rs
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
}
}
}
Expand All @@ -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
Expand Down
33 changes: 16 additions & 17 deletions src/librustc/middle/traits/select.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -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;
Expand All @@ -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 => {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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) => {
Expand Down Expand Up @@ -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()));

Expand Down Expand Up @@ -2207,7 +2207,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
trait_def_id,
nested);

let trait_obligations: Result<VecPerParamSpace<_>,()> = self.infcx.commit_if_ok(|snapshot| {
let trait_obligations: Result<Vec<_>,()> = 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);
Expand All @@ -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()));

Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -2568,9 +2569,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
_ => unreachable!()
};

Ok(VtableBuiltinData {
nested: VecPerParamSpace::new(nested, vec![], vec![])
})
Ok(VtableBuiltinData { nested: nested })
}

///////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -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<PredicateObligation<'tcx>>
-> Vec<PredicateObligation<'tcx>>
{
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
}

Expand Down
8 changes: 4 additions & 4 deletions src/librustc/middle/traits/util.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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<PredicateObligation<'tcx>>
-> Vec<PredicateObligation<'tcx>>
{
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>(
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/trans/common.rs
Expand Up @@ -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);
Expand Down

0 comments on commit 4b116fe

Please sign in to comment.