]> git.lizzy.rs Git - rust.git/commitdiff
Refactor away `inferred_obligations` from the trait selector
authorAravind Gollakota <aravindprasant@gmail.com>
Sun, 4 Mar 2018 00:47:17 +0000 (18:47 -0600)
committerAravind Gollakota <aravindprasant@gmail.com>
Sun, 4 Mar 2018 00:47:17 +0000 (18:47 -0600)
src/librustc/traits/mod.rs
src/librustc/traits/select.rs

index b9ae4599d808ea1ce2d1ef1e944be169138ee588..26ff5756ba0bb5647a1385f59b202f8a9ff2ad18 100644 (file)
@@ -854,19 +854,6 @@ pub fn nested_obligations(self) -> Vec<N> {
         }
     }
 
-    fn nested_obligations_mut(&mut self) -> &mut Vec<N> {
-        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<M, F>(self, f: F) -> Vtable<'tcx, M> where F: FnMut(N) -> M {
         match self {
             VtableImpl(i) => VtableImpl(VtableImplData {
index 9e24a4e6afacf5dcf91299035127957e63556db1..9ebc9152a488a24c3296078bf9f2b5eacf1233bd 100644 (file)
 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;
 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::Value>, _: 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<IntercrateMode>,
 
-    inferred_obligations: SnapshotVec<InferredObligationsSnapshotVecDelegate<'tcx>>,
-
     intercrate_ambiguity_causes: Option<Vec<IntercrateAmbiguityCause>>,
 
     /// Controls whether or not to filter out negative impls when selecting.
@@ -429,7 +417,6 @@ pub fn new(infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>) -> SelectionContext<'cx, 'gcx
             infcx,
             freshener: infcx.freshener(),
             intercrate: None,
-            inferred_obligations: SnapshotVec::new(),
             intercrate_ambiguity_causes: None,
             allow_negative_impls: false,
         }
@@ -442,7 +429,6 @@ pub fn intercrate(infcx: &'cx InferCtxt<'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 @@ pub fn with_negative(infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
             infcx,
             freshener: infcx.freshener(),
             intercrate: None,
-            inferred_obligations: SnapshotVec::new(),
             intercrate_ambiguity_causes: None,
             allow_negative_impls,
         }
@@ -498,8 +483,6 @@ pub fn closure_typer(&self) -> &'cx InferCtxt<'cx, 'gcx, 'tcx> {
     fn in_snapshot<R, F>(&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 @@ fn in_snapshot<R, F>(&mut self, f: F) -> R
     fn probe<R, F>(&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 @@ fn probe<R, F>(&mut self, f: F) -> R
     fn commit_if_ok<T, E, F>(&mut self, f: F) -> Result<T, E> where
         F: FnOnce(&mut Self, &infer::CombinedSnapshot) -> Result<T, E>
     {
-        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 @@ pub fn select(&mut self, obligation: &TraitObligation<'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 @@ fn evaluate_predicates_recursively<'a,'o,I>(&mut self,
                                                 stack: TraitObligationStackList<'o, 'tcx>,
                                                 predicates: I)
                                                 -> EvaluationResult
-        where I : Iterator<Item=&'a PredicateObligation<'tcx>>, 'tcx:'a
+        where I : IntoIterator<Item=&'a PredicateObligation<'tcx>>, 'tcx:'a
     {
         let mut result = EvaluatedToOk;
         for obligation in predicates {
@@ -695,7 +660,7 @@ fn evaluate_predicate_recursively<'o>(&mut self,
                 // 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 @@ fn evaluate_predicate_recursively<'o>(&mut self,
                 // 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 @@ fn match_projection(&mut self,
                         -> 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 @@ fn confirm_object_candidate(&mut self,
         };
 
         let mut upcast_trait_ref = None;
+        let mut nested = vec![];
         let vtable_base;
 
         {
@@ -2662,7 +2625,11 @@ fn confirm_object_candidate(&mut self,
                         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 @@ fn confirm_object_candidate(&mut self,
         VtableObjectData {
             upcast_trait_ref: upcast_trait_ref.unwrap(),
             vtable_base,
-            nested: vec![]
+            nested,
         }
     }
 
@@ -2737,7 +2704,7 @@ fn confirm_generator_candidate(&mut self,
             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 @@ fn confirm_generator_candidate(&mut self,
                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 @@ fn confirm_closure_candidate(&mut self,
                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 @@ fn confirm_poly_trait_refs(&mut self,
                                obligation_param_env: ty::ParamEnv<'tcx>,
                                obligation_trait_ref: ty::PolyTraitRef<'tcx>,
                                expected_trait_ref: ty::PolyTraitRef<'tcx>)
-                               -> Result<(), SelectionError<'tcx>>
+                               -> Result<Vec<PredicateObligation<'tcx>>, 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 @@ fn confirm_builtin_unsize_candidate(&mut self,
                     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 @@ fn confirm_builtin_unsize_candidate(&mut self,
                     self.infcx.at(&obligation.cause, obligation.param_env)
                               .eq(b, a)
                               .map_err(|_| Unimplemented)?;
-                self.inferred_obligations.extend(obligations);
+                nested.extend(obligations);
             }
 
             // Struct<T> -> Struct<U>.
@@ -3014,7 +2983,7 @@ fn confirm_builtin_unsize_candidate(&mut self,
                     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<T>: Unsize<Field<U>> predicate.
                 nested.push(tcx.predicate_for_trait_def(
@@ -3045,7 +3014,7 @@ fn confirm_builtin_unsize_candidate(&mut self,
                     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<U> predicate.
                 nested.push(tcx.predicate_for_trait_def(
@@ -3118,7 +3087,7 @@ fn match_impl(&mut self,
         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 @@ fn match_impl(&mut self,
 
         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 @@ fn match_impl(&mut self,
         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 @@ fn match_where_clause_trait_ref(&mut self,
                                     where_clause_trait_ref: ty::PolyTraitRef<'tcx>)
                                     -> Result<Vec<PredicateObligation<'tcx>>,()>
     {
-        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 @@ fn match_where_clause_trait_ref(&mut self,
     fn match_poly_trait_ref(&mut self,
                             obligation: &TraitObligation<'tcx>,
                             poly_trait_ref: ty::PolyTraitRef<'tcx>)
-                            -> Result<(),()>
+                            -> Result<Vec<PredicateObligation<'tcx>>,()>
     {
         debug!("match_poly_trait_ref: obligation={:?} poly_trait_ref={:?}",
                obligation,
@@ -3206,7 +3174,7 @@ fn match_poly_trait_ref(&mut self,
 
         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(|_| ())
     }