]> git.lizzy.rs Git - rust.git/commitdiff
traits: break apart the "full normalization" code used for normalizing
authorNiko Matsakis <niko@alum.mit.edu>
Sat, 14 Feb 2015 00:51:43 +0000 (19:51 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Wed, 18 Feb 2015 20:23:34 +0000 (15:23 -0500)
parameter environments so that it can be used elsewhere.

src/librustc/middle/traits/mod.rs

index 83090dd72aa94e33447a77e0e2b66472b1514b4c..57c9fa7a4d964a0b834e473247e2278f24631761 100644 (file)
@@ -15,9 +15,9 @@
 pub use self::Vtable::*;
 pub use self::ObligationCauseCode::*;
 
-use middle::mem_categorization::Typer;
 use middle::subst;
-use middle::ty::{self, Ty};
+use middle::ty::{self, HasProjectionTypes, Ty};
+use middle::ty_fold::TypeFoldable;
 use middle::infer::{self, InferCtxt};
 use std::slice::Iter;
 use std::rc::Rc;
@@ -432,18 +432,8 @@ pub fn normalize_param_env<'a,'tcx>(param_env: &ty::ParameterEnvironment<'a,'tcx
     debug!("normalize_param_env(param_env={})",
            param_env.repr(tcx));
 
-    let predicates: Vec<ty::Predicate<'tcx>> = {
-        let infcx = infer::new_infer_ctxt(tcx);
-        let mut selcx = &mut SelectionContext::new(&infcx, param_env);
-        let mut fulfill_cx = FulfillmentContext::new();
-        let Normalized { value: predicates, obligations } =
-            project::normalize(selcx, cause, &param_env.caller_bounds);
-        for obligation in obligations {
-            fulfill_cx.register_predicate_obligation(selcx.infcx(), obligation);
-        }
-        try!(fulfill_cx.select_all_or_error(selcx.infcx(), param_env));
-        predicates.iter().map(|p| infcx.resolve_type_vars_if_possible(p)).collect()
-    };
+    let infcx = infer::new_infer_ctxt(tcx);
+    let predicates = try!(fully_normalize(&infcx, param_env, cause, &param_env.caller_bounds));
 
     debug!("normalize_param_env: predicates={}",
            predicates.repr(tcx));
@@ -451,6 +441,35 @@ pub fn normalize_param_env<'a,'tcx>(param_env: &ty::ParameterEnvironment<'a,'tcx
     Ok(param_env.with_caller_bounds(predicates))
 }
 
+pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
+                                  closure_typer: &ty::ClosureTyper<'tcx>,
+                                  cause: ObligationCause<'tcx>,
+                                  value: &T)
+                                  -> Result<T, Vec<FulfillmentError<'tcx>>>
+    where T : TypeFoldable<'tcx> + HasProjectionTypes + Clone + Repr<'tcx>
+{
+    let tcx = closure_typer.tcx();
+
+    debug!("normalize_param_env(value={})",
+           value.repr(tcx));
+
+    let mut selcx = &mut SelectionContext::new(infcx, closure_typer);
+    let mut fulfill_cx = FulfillmentContext::new();
+    let Normalized { value: normalized_value, obligations } =
+        project::normalize(selcx, cause, value);
+    debug!("normalize_param_env: normalized_value={} obligations={}",
+           normalized_value.repr(tcx),
+           obligations.repr(tcx));
+    for obligation in obligations {
+        fulfill_cx.register_predicate_obligation(selcx.infcx(), obligation);
+    }
+    try!(fulfill_cx.select_all_or_error(infcx, closure_typer));
+    let resolved_value = infcx.resolve_type_vars_if_possible(&normalized_value);
+    debug!("normalize_param_env: resolved_value={}",
+           resolved_value.repr(tcx));
+    Ok(resolved_value)
+}
+
 impl<'tcx,O> Obligation<'tcx,O> {
     pub fn new(cause: ObligationCause<'tcx>,
                trait_ref: O)