Skip to content

Commit

Permalink
traits: break apart the "full normalization" code used for normalizing
Browse files Browse the repository at this point in the history
parameter environments so that it can be used elsewhere.
  • Loading branch information
nikomatsakis committed Feb 18, 2015
1 parent 7134ad4 commit 5511add
Showing 1 changed file with 33 additions and 14 deletions.
47 changes: 33 additions & 14 deletions src/librustc/middle/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ pub use self::FulfillmentErrorCode::*;
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;
Expand Down Expand Up @@ -432,25 +432,44 @@ 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));

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)
Expand Down

0 comments on commit 5511add

Please sign in to comment.