Move FufillmentContext into InferContext
This commit is contained in:
parent
e6596d0052
commit
6947948b4d
@ -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()
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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 =
|
||||
|
@ -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
|
||||
|
@ -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) =
|
||||
|
@ -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())
|
||||
{
|
||||
|
@ -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 ®ion_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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user