Skip to content

Commit 81f0b96

Browse files
committed
Refactor away inferred_obligations from the trait selector
1 parent 3b8bd53 commit 81f0b96

File tree

2 files changed

+40
-85
lines changed

2 files changed

+40
-85
lines changed

src/librustc/traits/mod.rs

-13
Original file line numberDiff line numberDiff line change
@@ -854,19 +854,6 @@ impl<'tcx, N> Vtable<'tcx, N> {
854854
}
855855
}
856856

857-
fn nested_obligations_mut(&mut self) -> &mut Vec<N> {
858-
match self {
859-
&mut VtableImpl(ref mut i) => &mut i.nested,
860-
&mut VtableParam(ref mut n) => n,
861-
&mut VtableBuiltin(ref mut i) => &mut i.nested,
862-
&mut VtableAutoImpl(ref mut d) => &mut d.nested,
863-
&mut VtableGenerator(ref mut c) => &mut c.nested,
864-
&mut VtableClosure(ref mut c) => &mut c.nested,
865-
&mut VtableObject(ref mut d) => &mut d.nested,
866-
&mut VtableFnPointer(ref mut d) => &mut d.nested,
867-
}
868-
}
869-
870857
pub fn map<M, F>(self, f: F) -> Vtable<'tcx, M> where F: FnMut(N) -> M {
871858
match self {
872859
VtableImpl(i) => VtableImpl(VtableImplData {

src/librustc/traits/select.rs

+40-72
Original file line numberDiff line numberDiff line change
@@ -44,27 +44,17 @@ use ty::relate::TypeRelation;
4444
use middle::lang_items;
4545

4646
use rustc_data_structures::bitvec::BitVector;
47-
use rustc_data_structures::snapshot_vec::{SnapshotVecDelegate, SnapshotVec};
4847
use std::iter;
4948
use std::cell::RefCell;
5049
use std::cmp;
5150
use std::fmt;
52-
use std::marker::PhantomData;
5351
use std::mem;
5452
use std::rc::Rc;
5553
use syntax::abi::Abi;
5654
use hir;
5755
use lint;
5856
use util::nodemap::{FxHashMap, FxHashSet};
5957

60-
struct InferredObligationsSnapshotVecDelegate<'tcx> {
61-
phantom: PhantomData<&'tcx i32>,
62-
}
63-
impl<'tcx> SnapshotVecDelegate for InferredObligationsSnapshotVecDelegate<'tcx> {
64-
type Value = PredicateObligation<'tcx>;
65-
type Undo = ();
66-
fn reverse(_: &mut Vec<Self::Value>, _: Self::Undo) {}
67-
}
6858

6959
pub struct SelectionContext<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
7060
infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
@@ -92,8 +82,6 @@ pub struct SelectionContext<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
9282
/// would satisfy it. This avoids crippling inference, basically.
9383
intercrate: Option<IntercrateMode>,
9484

95-
inferred_obligations: SnapshotVec<InferredObligationsSnapshotVecDelegate<'tcx>>,
96-
9785
intercrate_ambiguity_causes: Option<Vec<IntercrateAmbiguityCause>>,
9886

9987
/// Controls whether or not to filter out negative impls when selecting.
@@ -429,7 +417,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
429417
infcx,
430418
freshener: infcx.freshener(),
431419
intercrate: None,
432-
inferred_obligations: SnapshotVec::new(),
433420
intercrate_ambiguity_causes: None,
434421
allow_negative_impls: false,
435422
}
@@ -442,7 +429,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
442429
infcx,
443430
freshener: infcx.freshener(),
444431
intercrate: Some(mode),
445-
inferred_obligations: SnapshotVec::new(),
446432
intercrate_ambiguity_causes: None,
447433
allow_negative_impls: false,
448434
}
@@ -455,7 +441,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
455441
infcx,
456442
freshener: infcx.freshener(),
457443
intercrate: None,
458-
inferred_obligations: SnapshotVec::new(),
459444
intercrate_ambiguity_causes: None,
460445
allow_negative_impls,
461446
}
@@ -498,8 +483,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
498483
fn in_snapshot<R, F>(&mut self, f: F) -> R
499484
where F: FnOnce(&mut Self, &infer::CombinedSnapshot<'cx, 'tcx>) -> R
500485
{
501-
// The irrefutable nature of the operation means we don't need to snapshot the
502-
// inferred_obligations vector.
503486
self.infcx.in_snapshot(|snapshot| f(self, snapshot))
504487
}
505488

@@ -508,28 +491,15 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
508491
fn probe<R, F>(&mut self, f: F) -> R
509492
where F: FnOnce(&mut Self, &infer::CombinedSnapshot<'cx, 'tcx>) -> R
510493
{
511-
let inferred_obligations_snapshot = self.inferred_obligations.start_snapshot();
512-
let result = self.infcx.probe(|snapshot| f(self, snapshot));
513-
self.inferred_obligations.rollback_to(inferred_obligations_snapshot);
514-
result
494+
self.infcx.probe(|snapshot| f(self, snapshot))
515495
}
516496

517497
/// Wraps a commit_if_ok s.t. obligations collected during it are not returned in selection if
518498
/// the transaction fails and s.t. old obligations are retained.
519499
fn commit_if_ok<T, E, F>(&mut self, f: F) -> Result<T, E> where
520500
F: FnOnce(&mut Self, &infer::CombinedSnapshot) -> Result<T, E>
521501
{
522-
let inferred_obligations_snapshot = self.inferred_obligations.start_snapshot();
523-
match self.infcx.commit_if_ok(|snapshot| f(self, snapshot)) {
524-
Ok(ok) => {
525-
self.inferred_obligations.commit(inferred_obligations_snapshot);
526-
Ok(ok)
527-
},
528-
Err(err) => {
529-
self.inferred_obligations.rollback_to(inferred_obligations_snapshot);
530-
Err(err)
531-
}
532-
}
502+
self.infcx.commit_if_ok(|snapshot| f(self, snapshot))
533503
}
534504

535505

@@ -560,12 +530,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
560530
let stack = self.push_stack(TraitObligationStackList::empty(), obligation);
561531
let ret = match self.candidate_from_obligation(&stack)? {
562532
None => None,
563-
Some(candidate) => {
564-
let mut candidate = self.confirm_candidate(obligation, candidate)?;
565-
let inferred_obligations = (*self.inferred_obligations).into_iter().cloned();
566-
candidate.nested_obligations_mut().extend(inferred_obligations);
567-
Some(candidate)
568-
},
533+
Some(candidate) => Some(self.confirm_candidate(obligation, candidate)?)
569534
};
570535

571536
// Test whether this is a `()` which was produced by defaulting a
@@ -658,7 +623,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
658623
stack: TraitObligationStackList<'o, 'tcx>,
659624
predicates: I)
660625
-> EvaluationResult
661-
where I : Iterator<Item=&'a PredicateObligation<'tcx>>, 'tcx:'a
626+
where I : IntoIterator<Item=&'a PredicateObligation<'tcx>>, 'tcx:'a
662627
{
663628
let mut result = EvaluatedToOk;
664629
for obligation in predicates {
@@ -695,7 +660,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
695660
// does this code ever run?
696661
match self.infcx.equality_predicate(&obligation.cause, obligation.param_env, p) {
697662
Ok(InferOk { obligations, .. }) => {
698-
self.inferred_obligations.extend(obligations);
663+
self.evaluate_predicates_recursively(previous_stack, &obligations);
699664
EvaluatedToOk
700665
},
701666
Err(_) => EvaluatedToErr
@@ -706,7 +671,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
706671
// does this code ever run?
707672
match self.infcx.subtype_predicate(&obligation.cause, obligation.param_env, p) {
708673
Some(Ok(InferOk { obligations, .. })) => {
709-
self.inferred_obligations.extend(obligations);
674+
self.evaluate_predicates_recursively(previous_stack, &obligations);
710675
EvaluatedToOk
711676
},
712677
Some(Err(_)) => EvaluatedToErr,
@@ -1553,12 +1518,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
15531518
-> bool
15541519
{
15551520
assert!(!skol_trait_ref.has_escaping_regions());
1556-
match self.infcx.at(&obligation.cause, obligation.param_env)
1557-
.sup(ty::Binder(skol_trait_ref), trait_bound) {
1558-
Ok(InferOk { obligations, .. }) => {
1559-
self.inferred_obligations.extend(obligations);
1560-
}
1561-
Err(_) => { return false; }
1521+
if let Err(_) = self.infcx.at(&obligation.cause, obligation.param_env)
1522+
.sup(ty::Binder(skol_trait_ref), trait_bound) {
1523+
return false;
15621524
}
15631525

15641526
self.infcx.leak_check(false, obligation.cause.span, skol_map, snapshot).is_ok()
@@ -2644,6 +2606,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
26442606
};
26452607

26462608
let mut upcast_trait_ref = None;
2609+
let mut nested = vec![];
26472610
let vtable_base;
26482611

26492612
{
@@ -2662,7 +2625,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
26622625
self.commit_if_ok(
26632626
|this, _| this.match_poly_trait_ref(obligation, t))
26642627
{
2665-
Ok(_) => { upcast_trait_ref = Some(t); false }
2628+
Ok(obligations) => {
2629+
upcast_trait_ref = Some(t);
2630+
nested.extend(obligations);
2631+
false
2632+
}
26662633
Err(_) => { true }
26672634
}
26682635
});
@@ -2680,7 +2647,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
26802647
VtableObjectData {
26812648
upcast_trait_ref: upcast_trait_ref.unwrap(),
26822649
vtable_base,
2683-
nested: vec![]
2650+
nested,
26842651
}
26852652
}
26862653

@@ -2737,7 +2704,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
27372704
self.generator_trait_ref_unnormalized(obligation, closure_def_id, substs);
27382705
let Normalized {
27392706
value: trait_ref,
2740-
obligations
2707+
mut obligations
27412708
} = normalize_with_depth(self,
27422709
obligation.param_env,
27432710
obligation.cause.clone(),
@@ -2749,10 +2716,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
27492716
trait_ref,
27502717
obligations);
27512718

2752-
self.confirm_poly_trait_refs(obligation.cause.clone(),
2753-
obligation.param_env,
2754-
obligation.predicate.to_poly_trait_ref(),
2755-
trait_ref)?;
2719+
obligations.extend(
2720+
self.confirm_poly_trait_refs(obligation.cause.clone(),
2721+
obligation.param_env,
2722+
obligation.predicate.to_poly_trait_ref(),
2723+
trait_ref)?);
27562724

27572725
Ok(VtableGeneratorData {
27582726
closure_def_id: closure_def_id,
@@ -2798,10 +2766,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
27982766
trait_ref,
27992767
obligations);
28002768

2801-
self.confirm_poly_trait_refs(obligation.cause.clone(),
2802-
obligation.param_env,
2803-
obligation.predicate.to_poly_trait_ref(),
2804-
trait_ref)?;
2769+
obligations.extend(
2770+
self.confirm_poly_trait_refs(obligation.cause.clone(),
2771+
obligation.param_env,
2772+
obligation.predicate.to_poly_trait_ref(),
2773+
trait_ref)?);
28052774

28062775
obligations.push(Obligation::new(
28072776
obligation.cause.clone(),
@@ -2845,13 +2814,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
28452814
obligation_param_env: ty::ParamEnv<'tcx>,
28462815
obligation_trait_ref: ty::PolyTraitRef<'tcx>,
28472816
expected_trait_ref: ty::PolyTraitRef<'tcx>)
2848-
-> Result<(), SelectionError<'tcx>>
2817+
-> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>
28492818
{
28502819
let obligation_trait_ref = obligation_trait_ref.clone();
28512820
self.infcx
28522821
.at(&obligation_cause, obligation_param_env)
28532822
.sup(obligation_trait_ref, expected_trait_ref)
2854-
.map(|InferOk { obligations, .. }| self.inferred_obligations.extend(obligations))
2823+
.map(|InferOk { obligations, .. }| obligations)
28552824
.map_err(|e| OutputTypeParameterMismatch(expected_trait_ref, obligation_trait_ref, e))
28562825
}
28572826

@@ -2888,7 +2857,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
28882857
self.infcx.at(&obligation.cause, obligation.param_env)
28892858
.eq(target, new_trait)
28902859
.map_err(|_| Unimplemented)?;
2891-
self.inferred_obligations.extend(obligations);
2860+
nested.extend(obligations);
28922861

28932862
// Register one obligation for 'a: 'b.
28942863
let cause = ObligationCause::new(obligation.cause.span,
@@ -2950,7 +2919,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
29502919
self.infcx.at(&obligation.cause, obligation.param_env)
29512920
.eq(b, a)
29522921
.map_err(|_| Unimplemented)?;
2953-
self.inferred_obligations.extend(obligations);
2922+
nested.extend(obligations);
29542923
}
29552924

29562925
// Struct<T> -> Struct<U>.
@@ -3014,7 +2983,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
30142983
self.infcx.at(&obligation.cause, obligation.param_env)
30152984
.eq(target, new_struct)
30162985
.map_err(|_| Unimplemented)?;
3017-
self.inferred_obligations.extend(obligations);
2986+
nested.extend(obligations);
30182987

30192988
// Construct the nested Field<T>: Unsize<Field<U>> predicate.
30202989
nested.push(tcx.predicate_for_trait_def(
@@ -3045,7 +3014,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
30453014
self.infcx.at(&obligation.cause, obligation.param_env)
30463015
.eq(target, new_tuple)
30473016
.map_err(|_| Unimplemented)?;
3048-
self.inferred_obligations.extend(obligations);
3017+
nested.extend(obligations);
30493018

30503019
// Construct the nested T: Unsize<U> predicate.
30513020
nested.push(tcx.predicate_for_trait_def(
@@ -3118,7 +3087,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
31183087
let impl_trait_ref = impl_trait_ref.subst(self.tcx(),
31193088
impl_substs);
31203089

3121-
let impl_trait_ref =
3090+
let Normalized { value: impl_trait_ref, obligations: mut nested_obligations } =
31223091
project::normalize_with_depth(self,
31233092
obligation.param_env,
31243093
obligation.cause.clone(),
@@ -3134,12 +3103,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
31343103

31353104
let InferOk { obligations, .. } =
31363105
self.infcx.at(&obligation.cause, obligation.param_env)
3137-
.eq(skol_obligation_trait_ref, impl_trait_ref.value)
3106+
.eq(skol_obligation_trait_ref, impl_trait_ref)
31383107
.map_err(|e| {
31393108
debug!("match_impl: failed eq_trait_refs due to `{}`", e);
31403109
()
31413110
})?;
3142-
self.inferred_obligations.extend(obligations);
3111+
nested_obligations.extend(obligations);
31433112

31443113
if let Err(e) = self.infcx.leak_check(false,
31453114
obligation.cause.span,
@@ -3152,7 +3121,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
31523121
debug!("match_impl: success impl_substs={:?}", impl_substs);
31533122
Ok((Normalized {
31543123
value: impl_substs,
3155-
obligations: impl_trait_ref.obligations
3124+
obligations: nested_obligations
31563125
}, skol_map))
31573126
}
31583127

@@ -3189,24 +3158,23 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
31893158
where_clause_trait_ref: ty::PolyTraitRef<'tcx>)
31903159
-> Result<Vec<PredicateObligation<'tcx>>,()>
31913160
{
3192-
self.match_poly_trait_ref(obligation, where_clause_trait_ref)?;
3193-
Ok(Vec::new())
3161+
self.match_poly_trait_ref(obligation, where_clause_trait_ref)
31943162
}
31953163

31963164
/// Returns `Ok` if `poly_trait_ref` being true implies that the
31973165
/// obligation is satisfied.
31983166
fn match_poly_trait_ref(&mut self,
31993167
obligation: &TraitObligation<'tcx>,
32003168
poly_trait_ref: ty::PolyTraitRef<'tcx>)
3201-
-> Result<(),()>
3169+
-> Result<Vec<PredicateObligation<'tcx>>,()>
32023170
{
32033171
debug!("match_poly_trait_ref: obligation={:?} poly_trait_ref={:?}",
32043172
obligation,
32053173
poly_trait_ref);
32063174

32073175
self.infcx.at(&obligation.cause, obligation.param_env)
32083176
.sup(obligation.predicate.to_poly_trait_ref(), poly_trait_ref)
3209-
.map(|InferOk { obligations, .. }| self.inferred_obligations.extend(obligations))
3177+
.map(|InferOk { obligations, .. }| obligations)
32103178
.map_err(|_| ())
32113179
}
32123180

0 commit comments

Comments
 (0)