diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index b9ae4599d808e..26ff5756ba0bb 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -854,19 +854,6 @@ impl<'tcx, N> Vtable<'tcx, N> { } } - fn nested_obligations_mut(&mut self) -> &mut Vec { - match self { - &mut VtableImpl(ref mut i) => &mut i.nested, - &mut VtableParam(ref mut n) => n, - &mut VtableBuiltin(ref mut i) => &mut i.nested, - &mut VtableAutoImpl(ref mut d) => &mut d.nested, - &mut VtableGenerator(ref mut c) => &mut c.nested, - &mut VtableClosure(ref mut c) => &mut c.nested, - &mut VtableObject(ref mut d) => &mut d.nested, - &mut VtableFnPointer(ref mut d) => &mut d.nested, - } - } - pub fn map(self, f: F) -> Vtable<'tcx, M> where F: FnMut(N) -> M { match self { VtableImpl(i) => VtableImpl(VtableImplData { diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 9e24a4e6afacf..9ebc9152a488a 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -44,12 +44,10 @@ use ty::relate::TypeRelation; use middle::lang_items; use rustc_data_structures::bitvec::BitVector; -use rustc_data_structures::snapshot_vec::{SnapshotVecDelegate, SnapshotVec}; use std::iter; use std::cell::RefCell; use std::cmp; use std::fmt; -use std::marker::PhantomData; use std::mem; use std::rc::Rc; use syntax::abi::Abi; @@ -57,14 +55,6 @@ use hir; use lint; use util::nodemap::{FxHashMap, FxHashSet}; -struct InferredObligationsSnapshotVecDelegate<'tcx> { - phantom: PhantomData<&'tcx i32>, -} -impl<'tcx> SnapshotVecDelegate for InferredObligationsSnapshotVecDelegate<'tcx> { - type Value = PredicateObligation<'tcx>; - type Undo = (); - fn reverse(_: &mut Vec, _: Self::Undo) {} -} pub struct SelectionContext<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> { infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>, @@ -92,8 +82,6 @@ pub struct SelectionContext<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> { /// would satisfy it. This avoids crippling inference, basically. intercrate: Option, - inferred_obligations: SnapshotVec>, - intercrate_ambiguity_causes: Option>, /// Controls whether or not to filter out negative impls when selecting. @@ -429,7 +417,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { infcx, freshener: infcx.freshener(), intercrate: None, - inferred_obligations: SnapshotVec::new(), intercrate_ambiguity_causes: None, allow_negative_impls: false, } @@ -442,7 +429,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { infcx, freshener: infcx.freshener(), intercrate: Some(mode), - inferred_obligations: SnapshotVec::new(), intercrate_ambiguity_causes: None, allow_negative_impls: false, } @@ -455,7 +441,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { infcx, freshener: infcx.freshener(), intercrate: None, - inferred_obligations: SnapshotVec::new(), intercrate_ambiguity_causes: None, allow_negative_impls, } @@ -498,8 +483,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn in_snapshot(&mut self, f: F) -> R where F: FnOnce(&mut Self, &infer::CombinedSnapshot<'cx, 'tcx>) -> R { - // The irrefutable nature of the operation means we don't need to snapshot the - // inferred_obligations vector. self.infcx.in_snapshot(|snapshot| f(self, snapshot)) } @@ -508,10 +491,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn probe(&mut self, f: F) -> R where F: FnOnce(&mut Self, &infer::CombinedSnapshot<'cx, 'tcx>) -> R { - let inferred_obligations_snapshot = self.inferred_obligations.start_snapshot(); - let result = self.infcx.probe(|snapshot| f(self, snapshot)); - self.inferred_obligations.rollback_to(inferred_obligations_snapshot); - result + self.infcx.probe(|snapshot| f(self, snapshot)) } /// Wraps a commit_if_ok s.t. obligations collected during it are not returned in selection if @@ -519,17 +499,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn commit_if_ok(&mut self, f: F) -> Result where F: FnOnce(&mut Self, &infer::CombinedSnapshot) -> Result { - let inferred_obligations_snapshot = self.inferred_obligations.start_snapshot(); - match self.infcx.commit_if_ok(|snapshot| f(self, snapshot)) { - Ok(ok) => { - self.inferred_obligations.commit(inferred_obligations_snapshot); - Ok(ok) - }, - Err(err) => { - self.inferred_obligations.rollback_to(inferred_obligations_snapshot); - Err(err) - } - } + self.infcx.commit_if_ok(|snapshot| f(self, snapshot)) } @@ -560,12 +530,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let stack = self.push_stack(TraitObligationStackList::empty(), obligation); let ret = match self.candidate_from_obligation(&stack)? { None => None, - Some(candidate) => { - let mut candidate = self.confirm_candidate(obligation, candidate)?; - let inferred_obligations = (*self.inferred_obligations).into_iter().cloned(); - candidate.nested_obligations_mut().extend(inferred_obligations); - Some(candidate) - }, + Some(candidate) => Some(self.confirm_candidate(obligation, candidate)?) }; // Test whether this is a `()` which was produced by defaulting a @@ -658,7 +623,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { stack: TraitObligationStackList<'o, 'tcx>, predicates: I) -> EvaluationResult - where I : Iterator>, 'tcx:'a + where I : IntoIterator>, 'tcx:'a { let mut result = EvaluatedToOk; for obligation in predicates { @@ -695,7 +660,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // does this code ever run? match self.infcx.equality_predicate(&obligation.cause, obligation.param_env, p) { Ok(InferOk { obligations, .. }) => { - self.inferred_obligations.extend(obligations); + self.evaluate_predicates_recursively(previous_stack, &obligations); EvaluatedToOk }, Err(_) => EvaluatedToErr @@ -706,7 +671,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // does this code ever run? match self.infcx.subtype_predicate(&obligation.cause, obligation.param_env, p) { Some(Ok(InferOk { obligations, .. })) => { - self.inferred_obligations.extend(obligations); + self.evaluate_predicates_recursively(previous_stack, &obligations); EvaluatedToOk }, Some(Err(_)) => EvaluatedToErr, @@ -1553,12 +1518,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { -> bool { assert!(!skol_trait_ref.has_escaping_regions()); - match self.infcx.at(&obligation.cause, obligation.param_env) - .sup(ty::Binder(skol_trait_ref), trait_bound) { - Ok(InferOk { obligations, .. }) => { - self.inferred_obligations.extend(obligations); - } - Err(_) => { return false; } + if let Err(_) = self.infcx.at(&obligation.cause, obligation.param_env) + .sup(ty::Binder(skol_trait_ref), trait_bound) { + return false; } 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> { }; let mut upcast_trait_ref = None; + let mut nested = vec![]; let vtable_base; { @@ -2662,7 +2625,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { self.commit_if_ok( |this, _| this.match_poly_trait_ref(obligation, t)) { - Ok(_) => { upcast_trait_ref = Some(t); false } + Ok(obligations) => { + upcast_trait_ref = Some(t); + nested.extend(obligations); + false + } Err(_) => { true } } }); @@ -2680,7 +2647,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { VtableObjectData { upcast_trait_ref: upcast_trait_ref.unwrap(), vtable_base, - nested: vec![] + nested, } } @@ -2737,7 +2704,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { self.generator_trait_ref_unnormalized(obligation, closure_def_id, substs); let Normalized { value: trait_ref, - obligations + mut obligations } = normalize_with_depth(self, obligation.param_env, obligation.cause.clone(), @@ -2749,10 +2716,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { trait_ref, obligations); - self.confirm_poly_trait_refs(obligation.cause.clone(), - obligation.param_env, - obligation.predicate.to_poly_trait_ref(), - trait_ref)?; + obligations.extend( + self.confirm_poly_trait_refs(obligation.cause.clone(), + obligation.param_env, + obligation.predicate.to_poly_trait_ref(), + trait_ref)?); Ok(VtableGeneratorData { closure_def_id: closure_def_id, @@ -2798,10 +2766,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { trait_ref, obligations); - self.confirm_poly_trait_refs(obligation.cause.clone(), - obligation.param_env, - obligation.predicate.to_poly_trait_ref(), - trait_ref)?; + obligations.extend( + self.confirm_poly_trait_refs(obligation.cause.clone(), + obligation.param_env, + obligation.predicate.to_poly_trait_ref(), + trait_ref)?); obligations.push(Obligation::new( obligation.cause.clone(), @@ -2845,13 +2814,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation_param_env: ty::ParamEnv<'tcx>, obligation_trait_ref: ty::PolyTraitRef<'tcx>, expected_trait_ref: ty::PolyTraitRef<'tcx>) - -> Result<(), SelectionError<'tcx>> + -> Result>, SelectionError<'tcx>> { let obligation_trait_ref = obligation_trait_ref.clone(); self.infcx .at(&obligation_cause, obligation_param_env) .sup(obligation_trait_ref, expected_trait_ref) - .map(|InferOk { obligations, .. }| self.inferred_obligations.extend(obligations)) + .map(|InferOk { obligations, .. }| obligations) .map_err(|e| OutputTypeParameterMismatch(expected_trait_ref, obligation_trait_ref, e)) } @@ -2888,7 +2857,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { self.infcx.at(&obligation.cause, obligation.param_env) .eq(target, new_trait) .map_err(|_| Unimplemented)?; - self.inferred_obligations.extend(obligations); + nested.extend(obligations); // Register one obligation for 'a: 'b. let cause = ObligationCause::new(obligation.cause.span, @@ -2950,7 +2919,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { self.infcx.at(&obligation.cause, obligation.param_env) .eq(b, a) .map_err(|_| Unimplemented)?; - self.inferred_obligations.extend(obligations); + nested.extend(obligations); } // Struct -> Struct. @@ -3014,7 +2983,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { self.infcx.at(&obligation.cause, obligation.param_env) .eq(target, new_struct) .map_err(|_| Unimplemented)?; - self.inferred_obligations.extend(obligations); + nested.extend(obligations); // Construct the nested Field: Unsize> predicate. nested.push(tcx.predicate_for_trait_def( @@ -3045,7 +3014,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { self.infcx.at(&obligation.cause, obligation.param_env) .eq(target, new_tuple) .map_err(|_| Unimplemented)?; - self.inferred_obligations.extend(obligations); + nested.extend(obligations); // Construct the nested T: Unsize predicate. nested.push(tcx.predicate_for_trait_def( @@ -3118,7 +3087,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let impl_trait_ref = impl_trait_ref.subst(self.tcx(), impl_substs); - let impl_trait_ref = + let Normalized { value: impl_trait_ref, obligations: mut nested_obligations } = project::normalize_with_depth(self, obligation.param_env, obligation.cause.clone(), @@ -3134,12 +3103,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let InferOk { obligations, .. } = self.infcx.at(&obligation.cause, obligation.param_env) - .eq(skol_obligation_trait_ref, impl_trait_ref.value) + .eq(skol_obligation_trait_ref, impl_trait_ref) .map_err(|e| { debug!("match_impl: failed eq_trait_refs due to `{}`", e); () })?; - self.inferred_obligations.extend(obligations); + nested_obligations.extend(obligations); if let Err(e) = self.infcx.leak_check(false, obligation.cause.span, @@ -3152,7 +3121,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { debug!("match_impl: success impl_substs={:?}", impl_substs); Ok((Normalized { value: impl_substs, - obligations: impl_trait_ref.obligations + obligations: nested_obligations }, skol_map)) } @@ -3189,8 +3158,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { where_clause_trait_ref: ty::PolyTraitRef<'tcx>) -> Result>,()> { - self.match_poly_trait_ref(obligation, where_clause_trait_ref)?; - Ok(Vec::new()) + self.match_poly_trait_ref(obligation, where_clause_trait_ref) } /// Returns `Ok` if `poly_trait_ref` being true implies that the @@ -3198,7 +3166,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn match_poly_trait_ref(&mut self, obligation: &TraitObligation<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tcx>) - -> Result<(),()> + -> Result>,()> { debug!("match_poly_trait_ref: obligation={:?} poly_trait_ref={:?}", obligation, @@ -3206,7 +3174,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { self.infcx.at(&obligation.cause, obligation.param_env) .sup(obligation.predicate.to_poly_trait_ref(), poly_trait_ref) - .map(|InferOk { obligations, .. }| self.inferred_obligations.extend(obligations)) + .map(|InferOk { obligations, .. }| obligations) .map_err(|_| ()) }