Move FufillmentContext into InferContext

This commit is contained in:
Jared Roesch 2015-06-26 12:23:41 -07:00
parent e6596d0052
commit 6947948b4d
13 changed files with 48 additions and 29 deletions

View File

@ -87,6 +87,8 @@ pub struct InferCtxt<'a, 'tcx: 'a> {
pub parameter_environment: ty::ParameterEnvironment<'a, 'tcx>,
pub fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
// This is a temporary field used for toggling on normalization in the inference context,
// as we move towards the approach described here:
// https://internals.rust-lang.org/t/flattening-the-contexts-for-fun-and-profit/2293
@ -327,9 +329,16 @@ pub fn fixup_err_to_string(f: fixup_err) -> String {
}
}
/// errors_will_be_reported is required to proxy to the fulfillment context
/// FIXME -- a better option would be to hold back on modifying
/// the global cache until we know that all dependent obligations
/// are also satisfied. In that case, we could actually remove
/// this boolean flag, and we'd also avoid the problem of squelching
/// duplicate errors that occur across fns.
pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
tables: &'a RefCell<ty::Tables<'tcx>>,
param_env: Option<ty::ParameterEnvironment<'a, 'tcx>>)
param_env: Option<ty::ParameterEnvironment<'a, 'tcx>>,
errors_will_be_reported: bool)
-> InferCtxt<'a, 'tcx> {
InferCtxt {
tcx: tcx,
@ -339,6 +348,7 @@ pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
float_unification_table: RefCell::new(UnificationTable::new()),
region_vars: RegionVarBindings::new(tcx),
parameter_environment: param_env.unwrap_or(tcx.empty_parameter_environment()),
fulfillment_cx: RefCell::new(traits::FulfillmentContext::new(errors_will_be_reported)),
normalize: false,
err_count_on_creation: tcx.sess.err_count()
}
@ -1009,6 +1019,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
raw_ty.adjust(self.tcx,
expr.span,
expr.id,
raw_ty,
adjustment,
|method_call| self.tables
.borrow()

View File

@ -397,7 +397,7 @@ pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvi
let elaborated_env = unnormalized_env.with_caller_bounds(predicates);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(elaborated_env));
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(elaborated_env), false);
let predicates = match fully_normalize(&infcx, &infcx.parameter_environment, cause,
&infcx.parameter_environment.caller_bounds) {
Ok(predicates) => predicates,

View File

@ -957,7 +957,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
trait_ref, trait_ref.def_id());
tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id());
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, true);
// Do the initial selection for the obligation. This yields the
// shallow result we are looking for -- that is, what specific impl.
@ -1019,7 +1019,7 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
predicates);
let tcx = ccx.tcx();
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
let mut infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false);
let typer = NormalizingClosureTyper::new(tcx);
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
let mut fulfill_cx = traits::FulfillmentContext::new(false);

View File

@ -324,7 +324,7 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
// FIXME(#20304) -- cache
// NOTE: @jroesch
// Here is of an example where we do not use a param_env but use a typer instead.
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, true);
let typer = NormalizingClosureTyper::new(tcx);
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
let cause = traits::ObligationCause::dummy();

View File

@ -125,7 +125,7 @@ fn deduce_expectations_from_obligations<'a,'tcx>(
expected_vid: ty::TyVid)
-> (Option<ty::FnSig<'tcx>>, Option<ty::ClosureKind>)
{
let fulfillment_cx = fcx.inh.fulfillment_cx.borrow();
let fulfillment_cx = fcx.inh.infcx.fulfillment_cx.borrow();
// Here `expected_ty` is known to be a type inference variable.
let expected_sig =

View File

@ -43,7 +43,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
debug!("compare_impl_method: impl_trait_ref (liberated) = {:?}",
impl_trait_ref);
let mut infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
let mut infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, true);
let mut fulfillment_cx = traits::FulfillmentContext::new(true);
let trait_to_impl_substs = &impl_trait_ref.substs;
@ -419,7 +419,7 @@ pub fn compare_const_impl<'tcx>(tcx: &ty::ctxt<'tcx>,
debug!("compare_const_impl(impl_trait_ref={:?})",
impl_trait_ref);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, true);
let mut fulfillment_cx = traits::FulfillmentContext::new(true);
// The below is for the most part highly similar to the procedure

View File

@ -93,7 +93,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
ty: named_type } =
tcx.lookup_item_type(self_type_did);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false);
infcx.commit_if_ok(|snapshot| {
let (named_type_to_skolem, skol_map) =

View File

@ -159,7 +159,7 @@ pub struct Inherited<'a, 'tcx: 'a> {
fn_sig_map: RefCell<NodeMap<Vec<Ty<'tcx>>>>,
// Tracks trait obligations incurred during this function body.
fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
// fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
// When we process a call like `c()` where `c` is a closure type,
// we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
@ -295,11 +295,11 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> {
-> Inherited<'a, 'tcx> {
Inherited {
infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env)),
// I'm probably screwed here ... more boolean prop ...
infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env), false),
locals: RefCell::new(NodeMap()),
tables: tables,
fn_sig_map: RefCell::new(NodeMap()),
fulfillment_cx: RefCell::new(traits::FulfillmentContext::new(true)),
deferred_call_resolutions: RefCell::new(DefIdMap()),
deferred_cast_checks: RefCell::new(Vec::new()),
}
@ -313,7 +313,7 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> {
-> T
where T : TypeFoldable<'tcx> + HasTypeFlags
{
let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
let mut fulfillment_cx = self.infcx.fulfillment_cx.borrow_mut();
assoc::normalize_associated_types_in(&self.infcx,
typer,
&mut *fulfillment_cx, span,
@ -1389,7 +1389,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let cause = traits::ObligationCause::new(span,
self.body_id,
traits::ObligationCauseCode::MiscObligation);
self.inh.fulfillment_cx
self.inh
.infcx
.fulfillment_cx
.borrow_mut()
.normalize_projection_type(self.infcx(),
self.infcx(),
@ -1513,7 +1515,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
builtin_bound: ty::BuiltinBound,
cause: traits::ObligationCause<'tcx>)
{
self.inh.fulfillment_cx.borrow_mut()
self.inh.infcx.fulfillment_cx.borrow_mut()
.register_builtin_bound(self.infcx(), ty, builtin_bound, cause);
}
@ -1522,7 +1524,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
{
debug!("register_predicate({:?})",
obligation);
self.inh.fulfillment_cx
self.inh.infcx.fulfillment_cx
.borrow_mut()
.register_predicate_obligation(self.infcx(), obligation);
}
@ -1558,6 +1560,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let raw_ty = self.infcx().shallow_resolve(raw_ty);
let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| {
.method_map
self.inh.tables.borrow().method_map.get(&method_call)
.map(|method| resolve_ty(method.ty))
})
@ -1648,7 +1651,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
region: ty::Region,
cause: traits::ObligationCause<'tcx>)
{
let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut();
let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
fulfillment_cx.register_region_obligation(ty, region, cause);
}
@ -1747,7 +1750,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
self.select_all_obligations_and_apply_defaults();
let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut();
let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
match fulfillment_cx.select_all_or_error(self.infcx(), self.infcx()) {
Ok(()) => { }
Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
@ -1757,7 +1760,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Select as many obligations as we can at present.
fn select_obligations_where_possible(&self) {
match
self.inh.fulfillment_cx
self.inh.infcx.fulfillment_cx
.borrow_mut()
.select_where_possible(self.infcx(), self.infcx())
{
@ -1772,7 +1775,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// work.
fn select_new_obligations(&self) {
match
self.inh.fulfillment_cx
self.inh.infcx.fulfillment_cx
.borrow_mut()
.select_new_obligations(self.infcx(), self.infcx())
{

View File

@ -318,9 +318,13 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
// Make a copy of the region obligations vec because we'll need
// to be able to borrow the fulfillment-cx below when projecting.
let region_obligations =
self.fcx.inh.fulfillment_cx.borrow()
.region_obligations(node_id)
.to_vec();
self.fcx
.inh
.infcx
.fulfillment_cx
.borrow()
.region_obligations(node_id)
.to_vec();
for r_o in &region_obligations {
debug!("visit_region_obligations: r_o={:?}",
@ -332,7 +336,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
// Processing the region obligations should not cause the list to grow further:
assert_eq!(region_obligations.len(),
self.fcx.inh.fulfillment_cx.borrow().region_obligations(node_id).len());
self.fcx.inh.infcx.fulfillment_cx.borrow().region_obligations(node_id).len());
}
/// This method populates the region map's `free_region_map`. It walks over the transformed

View File

@ -448,7 +448,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
debug!("check_implementations_of_coerce_unsized: {:?} -> {:?} (free)",
source, target);
let infcx = new_infer_ctxt(tcx, &tcx.tables, Some(param_env));
let infcx = new_infer_ctxt(tcx, &tcx.tables, Some(param_env), true);
let check_mutbl = |mt_a: ty::mt<'tcx>, mt_b: ty::mt<'tcx>,
mk_ptr: &Fn(Ty<'tcx>) -> Ty<'tcx>| {
@ -632,7 +632,8 @@ fn subst_receiver_types_in_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
pub fn check_coherence(crate_context: &CrateCtxt) {
CoherenceChecker {
crate_context: crate_context,
inference_context: new_infer_ctxt(crate_context.tcx, &crate_context.tcx.tables, None),
// XXXJAREDXXX: not sure if the bool is right here?
inference_context: new_infer_ctxt(crate_context.tcx, &crate_context.tcx.tables, None, false),
inherent_impls: RefCell::new(FnvHashMap()),
}.check(crate_context.tcx.map.krate());
unsafety::check(crate_context.tcx);

View File

@ -133,7 +133,7 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
impl1_def_id,
impl2_def_id);
let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, None);
let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, None, false);
if traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id) {
self.report_overlap_error(trait_def_id, impl1_def_id, impl2_def_id);
}

View File

@ -2211,7 +2211,7 @@ fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
base_type,
base_type_free);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false);
drop(::require_same_types(tcx,
Some(&infcx),
false,

View File

@ -188,7 +188,7 @@ fn require_same_types<'a, 'tcx, M>(tcx: &ty::ctxt<'tcx>,
{
let result = match maybe_infcx {
None => {
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false);
infer::mk_eqty(&infcx, t1_is_expected, infer::Misc(span), t1, t2)
}
Some(infcx) => {