From 6947948b4df98b82a9e8f6847db442921edfc37b Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Fri, 26 Jun 2015 12:23:41 -0700 Subject: [PATCH 01/10] Move FufillmentContext into InferContext --- src/librustc/middle/infer/mod.rs | 13 ++++++++++- src/librustc/middle/traits/mod.rs | 2 +- src/librustc_trans/trans/common.rs | 4 ++-- src/librustc_trans/trans/monomorphize.rs | 2 +- src/librustc_typeck/check/closure.rs | 2 +- src/librustc_typeck/check/compare_method.rs | 4 ++-- src/librustc_typeck/check/dropck.rs | 2 +- src/librustc_typeck/check/mod.rs | 25 ++++++++++++--------- src/librustc_typeck/check/regionck.rs | 12 ++++++---- src/librustc_typeck/coherence/mod.rs | 5 +++-- src/librustc_typeck/coherence/overlap.rs | 2 +- src/librustc_typeck/collect.rs | 2 +- src/librustc_typeck/lib.rs | 2 +- 13 files changed, 48 insertions(+), 29 deletions(-) diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index c355e8b82a6..4617d3860a3 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -87,6 +87,8 @@ pub struct InferCtxt<'a, 'tcx: 'a> { pub parameter_environment: ty::ParameterEnvironment<'a, 'tcx>, + pub fulfillment_cx: RefCell>, + // 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>, - param_env: Option>) + param_env: Option>, + 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() diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index 9df6ed5d681..c5afb7dd3db 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -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, diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 9c2aea1e67a..32a1f74063b 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -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); diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index 67ccf64621a..6ad164719cf 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -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(); diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index b5ee46ece94..6d1e9dfacf2 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -125,7 +125,7 @@ fn deduce_expectations_from_obligations<'a,'tcx>( expected_vid: ty::TyVid) -> (Option>, Option) { - 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 = diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index f62411e8582..6375926298f 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -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 diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 6f0fbfebf46..7d911cf8b03 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -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) = diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 2db1598db4b..76286cfe9ba 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -159,7 +159,7 @@ pub struct Inherited<'a, 'tcx: 'a> { fn_sig_map: RefCell>>>, // Tracks trait obligations incurred during this function body. - fulfillment_cx: RefCell>, + // fulfillment_cx: RefCell>, // 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()) { diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index a8630190738..661e1856ce8 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -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 diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index fbabc287342..23336c43995 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -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); diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs index 3495714fcc7..42c6bcbfbb9 100644 --- a/src/librustc_typeck/coherence/overlap.rs +++ b/src/librustc_typeck/coherence/overlap.rs @@ -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); } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 7909908079f..c45fbb70002 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -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, diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 48a64675c70..8c3ef4ae631 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -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) => { From 64f1a59daf4b7b5cbab1730f3b10fb73745d3b5e Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Sat, 27 Jun 2015 17:37:13 -0700 Subject: [PATCH 02/10] Update all uses of FulfillmentContext Update all uses of FulfillmentContext to be ones obtained via an InferCtxt. This is another step of flattening the type checking context into a single piece of state. --- src/librustc/middle/check_const.rs | 2 +- src/librustc/middle/traits/mod.rs | 5 +++-- src/librustc_trans/trans/common.rs | 6 +++--- src/librustc_trans/trans/monomorphize.rs | 3 ++- src/librustc_typeck/check/compare_method.rs | 4 ++-- src/librustc_typeck/coherence/mod.rs | 2 +- 6 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 8bbb6ae757f..16193e11b41 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -284,8 +284,8 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { fn check_static_type(&self, e: &ast::Expr) { let ty = self.tcx.node_id_to_type(e.id); let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, None); - let mut fulfill_cx = traits::FulfillmentContext::new(false); let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic); + let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause); match fulfill_cx.select_all_or_error(&infcx, &infcx.parameter_environment) { Ok(()) => { }, diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index c5afb7dd3db..ff84c1755a4 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -322,7 +322,7 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, ty, bound); - let mut fulfill_cx = FulfillmentContext::new(false); + let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); // We can use a dummy node-id here because we won't pay any mind // to region obligations that arise (there shouldn't really be any @@ -438,7 +438,8 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, debug!("normalize_param_env(value={:?})", value); let mut selcx = &mut SelectionContext::new(infcx, closure_typer); - let mut fulfill_cx = FulfillmentContext::new(false); + let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); + let Normalized { value: normalized_value, obligations } = project::normalize(selcx, cause, value); debug!("normalize_param_env: normalized_value={:?} obligations={:?}", diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 32a1f74063b..92aeb9f7b72 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -994,7 +994,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // Currently, we use a fulfillment context to completely resolve // all nested obligations. This is because they can inform the // inference of the impl's type parameters. - let mut fulfill_cx = traits::FulfillmentContext::new(true); + let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); let vtable = selection.map(|predicate| { fulfill_cx.register_predicate_obligation(&infcx, predicate); }); @@ -1019,10 +1019,10 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, predicates); let tcx = ccx.tcx(); - let mut infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false); + let 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); + let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); let cause = traits::ObligationCause::dummy(); let traits::Normalized { value: predicates, obligations } = traits::normalize(&mut selcx, cause.clone(), &predicates); diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index 6ad164719cf..b88251c69a0 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -335,7 +335,8 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T result, obligations); - let mut fulfill_cx = traits::FulfillmentContext::new(true); + let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); + for obligation in obligations { fulfill_cx.register_predicate_obligation(&infcx, obligation); } diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 6375926298f..85478945e1c 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -44,7 +44,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, impl_trait_ref); let mut infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, true); - let mut fulfillment_cx = traits::FulfillmentContext::new(true); + let mut fulfillment_cx = infcx.fulfillment_cx.borrow_mut(); let trait_to_impl_substs = &impl_trait_ref.substs; @@ -420,7 +420,7 @@ pub fn compare_const_impl<'tcx>(tcx: &ty::ctxt<'tcx>, impl_trait_ref); let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, true); - let mut fulfillment_cx = traits::FulfillmentContext::new(true); + let mut fulfillment_cx = infcx.fulfillment_cx.borrow_mut(); // The below is for the most part highly similar to the procedure // for methods above. It is simpler in many respects, especially diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 23336c43995..9705cfae4d3 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -531,7 +531,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { } }; - let mut fulfill_cx = traits::FulfillmentContext::new(true); + let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); // Register an obligation for `A: Trait`. let cause = traits::ObligationCause::misc(span, impl_did.node); From 0f13a3f361384c278041c95e9a2ba9975e6cde71 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Sat, 27 Jun 2015 17:37:22 -0700 Subject: [PATCH 03/10] Use fresh FulfillmentContexts in select locations --- src/librustc/middle/check_const.rs | 2 +- src/librustc/middle/const_eval.rs | 2 +- src/librustc/middle/infer/mod.rs | 1 - src/librustc/middle/traits/fulfill.rs | 2 +- src/librustc/middle/traits/mod.rs | 14 ++++++++++++-- src/librustc/middle/ty.rs | 2 +- src/librustc_typeck/check/mod.rs | 7 +++---- src/librustc_typeck/coherence/mod.rs | 4 ++-- 8 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 16193e11b41..95a598ad115 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -283,7 +283,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { fn check_static_type(&self, e: &ast::Expr) { let ty = self.tcx.node_id_to_type(e.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); let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic); let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause); diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index a6b7d7f832a..7d4553c8b14 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -1031,7 +1031,7 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>, substs: trait_substs }); 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, false); let mut selcx = traits::SelectionContext::new(&infcx, &infcx.parameter_environment); let obligation = traits::Obligation::new(traits::ObligationCause::dummy(), diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 4617d3860a3..04c29aaeb5a 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -1019,7 +1019,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { raw_ty.adjust(self.tcx, expr.span, expr.id, - raw_ty, adjustment, |method_call| self.tables .borrow() diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs index dc3ccd417b8..a769ef8233e 100644 --- a/src/librustc/middle/traits/fulfill.rs +++ b/src/librustc/middle/traits/fulfill.rs @@ -85,7 +85,7 @@ pub struct FulfillmentContext<'tcx> { // particular node-id). region_obligations: NodeMap>>, - errors_will_be_reported: bool, + pub errors_will_be_reported: bool, } #[derive(Clone)] diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index ff84c1755a4..c398a24f4f6 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -322,7 +322,7 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, ty, bound); - let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); + let mut fulfill_cx = FulfillmentContext::new(false); // We can use a dummy node-id here because we won't pay any mind // to region obligations that arise (there shouldn't really be any @@ -438,7 +438,17 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, debug!("normalize_param_env(value={:?})", value); let mut selcx = &mut SelectionContext::new(infcx, closure_typer); - let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); + // FIXME (@jroesch): I'm not sure if this is a bug or not, needs + // further investigation. It appears that by reusing the fulfillment_cx + // here we incur more obligations and later trip an asssertion on + // regionck.rs line 337. The two possibilities I see is that + // normalization is not actually fully happening and we + // have a bug else where or that we are adding a duplicate + // bound into the list causing its size to change. I think + // we should probably land this refactor and then come + // back to this is a follow-up patch. + let mut fulfill_cx = FulfillmentContext::new(false); + // let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); let Normalized { value: normalized_value, obligations } = project::normalize(selcx, cause, value); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index fe52fba49c6..8e5b6f4d450 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -4401,7 +4401,7 @@ impl<'tcx> TyS<'tcx> { -> bool { let tcx = param_env.tcx(); - let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(param_env.clone())); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(param_env.clone()), false); let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, param_env, self, bound, span); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 76286cfe9ba..806bcb2306b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -295,8 +295,7 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> { -> Inherited<'a, 'tcx> { Inherited { - // I'm probably screwed here ... more boolean prop ... - infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env), false), + infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env), true), locals: RefCell::new(NodeMap()), tables: tables, fn_sig_map: RefCell::new(NodeMap()), @@ -316,7 +315,8 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> { let mut fulfillment_cx = self.infcx.fulfillment_cx.borrow_mut(); assoc::normalize_associated_types_in(&self.infcx, typer, - &mut *fulfillment_cx, span, + &mut fulfillment_cx, + span, body_id, value) } @@ -1560,7 +1560,6 @@ 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)) }) diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 9705cfae4d3..1219f2928c1 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -531,7 +531,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { } }; - let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); + let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); // Register an obligation for `A: Trait`. let cause = traits::ObligationCause::misc(span, impl_did.node); @@ -633,7 +633,7 @@ pub fn check_coherence(crate_context: &CrateCtxt) { CoherenceChecker { crate_context: crate_context, // XXXJAREDXXX: not sure if the bool is right here? - inference_context: new_infer_ctxt(crate_context.tcx, &crate_context.tcx.tables, None, false), + inference_context: new_infer_ctxt(crate_context.tcx, &crate_context.tcx.tables, None, true), inherent_impls: RefCell::new(FnvHashMap()), }.check(crate_context.tcx.map.krate()); unsafety::check(crate_context.tcx); From fb295a60b37fc2bc60fab29fad1863a174fa587c Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Sat, 27 Jun 2015 22:04:15 -0700 Subject: [PATCH 04/10] Remove NormalizingClosureTyper --- src/librustc/middle/infer/mod.rs | 164 +++++++++++++++++- src/librustc_trans/trans/adt.rs | 9 +- src/librustc_trans/trans/attributes.rs | 5 +- src/librustc_trans/trans/base.rs | 5 +- src/librustc_trans/trans/closure.rs | 10 +- src/librustc_trans/trans/common.rs | 81 ++------- .../trans/debuginfo/metadata.rs | 11 +- src/librustc_trans/trans/declare.rs | 6 +- src/librustc_trans/trans/monomorphize.rs | 7 +- 9 files changed, 204 insertions(+), 94 deletions(-) diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 04c29aaeb5a..91fee77f0a7 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -19,6 +19,7 @@ pub use self::TypeOrigin::*; pub use self::ValuePairs::*; pub use self::fixup_err::*; pub use middle::ty::IntVarValue; +use middle::ty::ClosureTyper; pub use self::freshen::TypeFreshener; pub use self::region_inference::GenericKind; @@ -29,7 +30,8 @@ use middle::region::CodeExtent; use middle::subst; use middle::subst::Substs; use middle::subst::Subst; -use middle::traits; +use middle::traits::{self, FulfillmentContext, Normalized, MiscObligation, + SelectionContext, ObligationCause}; use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, UnconstrainedNumeric}; use middle::ty::{self, Ty, HasTypeFlags}; use middle::ty_fold::{self, TypeFolder, TypeFoldable}; @@ -39,7 +41,7 @@ use std::cell::{RefCell, Ref}; use std::fmt; use syntax::ast; use syntax::codemap; -use syntax::codemap::Span; +use syntax::codemap::{Span, DUMMY_SP}; use util::nodemap::{FnvHashMap, NodeMap}; use self::combine::CombineFields; @@ -354,6 +356,14 @@ pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>, } } +pub fn normalizing_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>, + tables: &'a RefCell>) + -> InferCtxt<'a, 'tcx> { + let mut infcx = new_infer_ctxt(tcx, tables, None, false); + infcx.normalize = true; + infcx +} + /// Computes the least upper-bound of `a` and `b`. If this is not possible, reports an error and /// returns ty::err. pub fn common_supertype<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>, @@ -557,7 +567,8 @@ impl<'a, 'tcx> ty::ClosureTyper<'tcx> for InferCtxt<'a, 'tcx> { // the substitutions in `substs` are already monomorphized, // but we still must normalize associated types // normalize_associated_type(self.param_env.tcx, &closure_ty) - panic!("see issue 26597: fufillment context refactor must occur") + normalize_associated_type(&self.tcx, &closure_ty) + // panic!("see issue 26597: fufillment context refactor must occur") } else { closure_ty } @@ -579,13 +590,158 @@ impl<'a, 'tcx> ty::ClosureTyper<'tcx> for InferCtxt<'a, 'tcx> { // the substitutions in `substs` are already monomorphized, // but we still must normalize associated types // monomorphize::normalize_associated_type(self.param_env.tcx, &result) - panic!("see issue 26597: fufillment context refactor must occur") + // panic!("see issue 26597: fufillment context refactor must occur") + normalize_associated_type(&self.tcx, &result) } else { result } } } +pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T + where T : TypeFoldable<'tcx> + HasTypeFlags +{ + debug!("normalize_associated_type(t={:?})", value); + + let value = erase_regions(tcx, value); + + if !value.has_projection_types() { + return value; + } + + let infcx = new_infer_ctxt(tcx, &tcx.tables, None, true); + let mut selcx = traits::SelectionContext::new(&infcx, &infcx); + let cause = traits::ObligationCause::dummy(); + let traits::Normalized { value: result, obligations } = + traits::normalize(&mut selcx, cause, &value); + + debug!("normalize_associated_type: result={:?} obligations={:?}", + result, + obligations); + + let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); + + for obligation in obligations { + fulfill_cx.register_predicate_obligation(&infcx, obligation); + } + + let result = drain_fulfillment_cx_or_panic(DUMMY_SP, &infcx, &mut fulfill_cx, &result); + + result +} + +pub fn drain_fulfillment_cx_or_panic<'a,'tcx,T>(span: Span, + infcx: &InferCtxt<'a,'tcx>, + fulfill_cx: &mut traits::FulfillmentContext<'tcx>, + result: &T) + -> T + where T : TypeFoldable<'tcx> +{ + match drain_fulfillment_cx(infcx, fulfill_cx, result) { + Ok(v) => v, + Err(errors) => { + infcx.tcx.sess.span_bug( + span, + &format!("Encountered errors `{:?}` fulfilling during trans", + errors)); + } + } +} + +/// Finishes processes any obligations that remain in the fulfillment +/// context, and then "freshens" and returns `result`. This is +/// primarily used during normalization and other cases where +/// processing the obligations in `fulfill_cx` may cause type +/// inference variables that appear in `result` to be unified, and +/// hence we need to process those obligations to get the complete +/// picture of the type. +pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, + fulfill_cx: &mut traits::FulfillmentContext<'tcx>, + result: &T) + -> Result>> + where T : TypeFoldable<'tcx> +{ + debug!("drain_fulfillment_cx(result={:?})", + result); + // this is stupid but temporary + let typer: &ClosureTyper<'tcx> = infcx; + // In principle, we only need to do this so long as `result` + // contains unbound type parameters. It could be a slight + // optimization to stop iterating early. + match fulfill_cx.select_all_or_error(infcx, typer) { + Ok(()) => { } + Err(errors) => { + return Err(errors); + } + } + + // Use freshen to simultaneously replace all type variables with + // their bindings and replace all regions with 'static. This is + // sort of overkill because we do not expect there to be any + // unbound type variables, hence no `TyFresh` types should ever be + // inserted. + Ok(result.fold_with(&mut infcx.freshener())) +} + +/// Returns an equivalent value with all free regions removed (note +/// that late-bound regions remain, because they are important for +/// subtyping, but they are anonymized and normalized as well). This +/// is a stronger, caching version of `ty_fold::erase_regions`. +pub fn erase_regions<'tcx,T>(cx: &ty::ctxt<'tcx>, value: &T) -> T + where T : TypeFoldable<'tcx> +{ + let value1 = value.fold_with(&mut RegionEraser(cx)); + debug!("erase_regions({:?}) = {:?}", + value, value1); + return value1; + + struct RegionEraser<'a, 'tcx: 'a>(&'a ty::ctxt<'tcx>); + + impl<'a, 'tcx> TypeFolder<'tcx> for RegionEraser<'a, 'tcx> { + fn tcx(&self) -> &ty::ctxt<'tcx> { self.0 } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + match self.tcx().normalized_cache.borrow().get(&ty).cloned() { + None => {} + Some(u) => return u + } + + let t_norm = ty_fold::super_fold_ty(self, ty); + self.tcx().normalized_cache.borrow_mut().insert(ty, t_norm); + return t_norm; + } + + fn fold_binder(&mut self, t: &ty::Binder) -> ty::Binder + where T : TypeFoldable<'tcx> + { + let u = self.tcx().anonymize_late_bound_regions(t); + ty_fold::super_fold_binder(self, &u) + } + + fn fold_region(&mut self, r: ty::Region) -> ty::Region { + // because late-bound regions affect subtyping, we can't + // erase the bound/free distinction, but we can replace + // all free regions with 'static. + // + // Note that we *CAN* replace early-bound regions -- the + // type system never "sees" those, they get substituted + // away. In trans, they will always be erased to 'static + // whenever a substitution occurs. + match r { + ty::ReLateBound(..) => r, + _ => ty::ReStatic + } + } + + fn fold_substs(&mut self, + substs: &subst::Substs<'tcx>) + -> subst::Substs<'tcx> { + subst::Substs { regions: subst::ErasedRegions, + types: substs.types.fold_with(self) } + } + } +} + impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn freshen>(&self, t: T) -> T { t.fold_with(&mut self.freshener()) diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs index 3ce76167e85..b96dcf940a8 100644 --- a/src/librustc_trans/trans/adt.rs +++ b/src/librustc_trans/trans/adt.rs @@ -50,6 +50,7 @@ use std::rc::Rc; use llvm::{ValueRef, True, IntEQ, IntNE}; use back::abi::FAT_PTR_ADDR; use middle::subst; +use middle::infer; use middle::ty::{self, Ty, ClosureTyper}; use middle::ty::Disr; use syntax::ast; @@ -223,8 +224,8 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, Univariant(mk_struct(cx, &ftys[..], packed, t), dtor_to_init_u8(dtor)) } ty::TyClosure(def_id, substs) => { - let typer = NormalizingClosureTyper::new(cx.tcx()); - let upvars = typer.closure_upvars(def_id, substs).unwrap(); + let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables); + let upvars = infcx.closure_upvars(def_id, substs).unwrap(); let upvar_types = upvars.iter().map(|u| u.ty).collect::>(); Univariant(mk_struct(cx, &upvar_types[..], false, t), 0) } @@ -443,8 +444,8 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>, // Perhaps one of the upvars of this struct is non-zero // Let's recurse and find out! ty::TyClosure(def_id, substs) => { - let typer = NormalizingClosureTyper::new(tcx); - let upvars = typer.closure_upvars(def_id, substs).unwrap(); + let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables); + let upvars = infcx.closure_upvars(def_id, substs).unwrap(); let upvar_types = upvars.iter().map(|u| u.ty).collect::>(); for (j, &ty) in upvar_types.iter().enumerate() { diff --git a/src/librustc_trans/trans/attributes.rs b/src/librustc_trans/trans/attributes.rs index b432560bc4b..fd704ed2d37 100644 --- a/src/librustc_trans/trans/attributes.rs +++ b/src/librustc_trans/trans/attributes.rs @@ -12,6 +12,7 @@ use libc::{c_uint, c_ulonglong}; use llvm::{self, ValueRef, AttrHelper}; use middle::ty::{self, ClosureTyper}; +use middle::infer; use session::config::NoDebugInfo; use syntax::abi; use syntax::ast; @@ -145,8 +146,8 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx let (fn_sig, abi, env_ty) = match fn_type.sty { ty::TyBareFn(_, ref f) => (&f.sig, f.abi, None), ty::TyClosure(closure_did, substs) => { - let typer = common::NormalizingClosureTyper::new(ccx.tcx()); - function_type = typer.closure_type(closure_did, substs); + let infcx = infer::normalizing_infer_ctxt(ccx.tcx(), &ccx.tcx().tables); + function_type = infcx.closure_type(closure_did, substs); let self_type = base::self_type_for_closure(ccx, closure_did, fn_type); (&function_type.sig, abi::RustCall, Some(self_type)) } diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 0cd6bbad03a..088df7288be 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -37,6 +37,7 @@ use llvm; use metadata::{csearch, encoder, loader}; use middle::astencode; use middle::cfg; +use middle::infer; use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem}; use middle::weak_lang_items; use middle::subst::Substs; @@ -434,8 +435,8 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>, } ty::TyClosure(def_id, substs) => { let repr = adt::represent_type(cx.ccx(), t); - let typer = common::NormalizingClosureTyper::new(cx.tcx()); - let upvars = typer.closure_upvars(def_id, substs).unwrap(); + let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables); + let upvars = infcx.closure_upvars(def_id, substs).unwrap(); for (i, upvar) in upvars.iter().enumerate() { let llupvar = adt::trans_field_ptr(cx, &*repr, data_ptr, 0, i); cx = f(cx, llupvar, upvar.ty); diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index b6378062855..c9bab6861ca 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -12,6 +12,7 @@ use arena::TypedArena; use back::link::{self, mangle_internal_name_by_path_and_seq}; use llvm::{ValueRef, get_params}; use middle::mem_categorization::Typer; +use middle::infer; use trans::adt; use trans::attributes; use trans::base::*; @@ -214,8 +215,9 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>, // takes the same set of type arguments as the enclosing fn, and // this function (`trans_closure`) is invoked at the point // of the closure expression. - let typer = NormalizingClosureTyper::new(tcx); - let function_type = typer.closure_type(closure_id, param_substs); + + let infcx = infer::normalizing_infer_ctxt(ccx.tcx(), &ccx.tcx().tables); + let function_type = infcx.closure_type(closure_id, param_substs); let freevars: Vec = tcx.with_freevars(id, |fv| fv.iter().cloned().collect()); @@ -358,7 +360,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>( ccx.tn().val_to_string(llreffn)); let tcx = ccx.tcx(); - let typer = NormalizingClosureTyper::new(tcx); + let infcx = infer::normalizing_infer_ctxt(ccx.tcx(), &ccx.tcx().tables); // Find a version of the closure type. Substitute static for the // region since it doesn't really matter. @@ -367,7 +369,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>( let ref_closure_ty = tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic), closure_ty); // Make a version with the type of by-ref closure. - let ty::ClosureTy { unsafety, abi, mut sig } = typer.closure_type(closure_def_id, substs); + let ty::ClosureTy { unsafety, abi, mut sig } = infcx.closure_type(closure_def_id, substs); sig.0.inputs.insert(0, ref_closure_ty); // sig has no self type as of yet let llref_bare_fn_ty = tcx.mk_bare_fn(ty::BareFnTy { unsafety: unsafety, abi: abi, diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 92aeb9f7b72..1fc68790db0 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -24,6 +24,7 @@ use middle::infer; use middle::lang_items::LangItem; use middle::mem_categorization as mc; use middle::mem_categorization::Typer; +use middle::ty::ClosureTyper; use middle::region; use middle::subst::{self, Substs}; use trans::base; @@ -642,8 +643,8 @@ impl<'blk, 'tcx> ty::ClosureTyper<'tcx> for BlockS<'blk, 'tcx> { def_id: ast::DefId) -> Option { - let typer = NormalizingClosureTyper::new(self.tcx()); - typer.closure_kind(def_id) + let infcx = infer::normalizing_infer_ctxt(self.tcx(), &self.tcx().tables); + infcx.closure_kind(def_id) } fn closure_type(&self, @@ -651,8 +652,8 @@ impl<'blk, 'tcx> ty::ClosureTyper<'tcx> for BlockS<'blk, 'tcx> { substs: &subst::Substs<'tcx>) -> ty::ClosureTy<'tcx> { - let typer = NormalizingClosureTyper::new(self.tcx()); - typer.closure_type(def_id, substs) + let infcx = infer::normalizing_infer_ctxt(self.tcx(), &self.tcx().tables); + infcx.closure_type(def_id, substs) } fn closure_upvars(&self, @@ -660,8 +661,8 @@ impl<'blk, 'tcx> ty::ClosureTyper<'tcx> for BlockS<'blk, 'tcx> { substs: &Substs<'tcx>) -> Option>> { - let typer = NormalizingClosureTyper::new(self.tcx()); - typer.closure_upvars(def_id, substs) + let infcx = infer::new_infer_ctxt(self.tcx(), &self.tcx().tables, None, true); + infcx.closure_upvars(def_id, substs) } } @@ -957,12 +958,12 @@ 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, true); // Do the initial selection for the obligation. This yields the // shallow result we are looking for -- that is, what specific impl. - let typer = NormalizingClosureTyper::new(tcx); - let mut selcx = traits::SelectionContext::new(&infcx, &typer); + let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables); + let mut selcx = traits::SelectionContext::new(&infcx, &infcx); + let obligation = traits::Obligation::new(traits::ObligationCause::misc(span, ast::DUMMY_NODE_ID), trait_ref.to_poly_trait_predicate()); @@ -1019,9 +1020,8 @@ 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, false); - let typer = NormalizingClosureTyper::new(tcx); - let mut selcx = traits::SelectionContext::new(&infcx, &typer); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, true); + let mut selcx = traits::SelectionContext::new(&infcx, &infcx); let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); let cause = traits::ObligationCause::dummy(); let traits::Normalized { value: predicates, obligations } = @@ -1036,57 +1036,6 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, drain_fulfillment_cx(&infcx, &mut fulfill_cx, &()).is_ok() } -// NOTE: here is another use of parameter environment without an InferCtxt, -// this is obviously related to the typer interface requiring a parameter env. -// We should pay attention to this when refactoring -// - @jroesch -pub struct NormalizingClosureTyper<'a,'tcx:'a> { - param_env: ty::ParameterEnvironment<'a, 'tcx> -} - -impl<'a,'tcx> NormalizingClosureTyper<'a,'tcx> { - pub fn new(tcx: &'a ty::ctxt<'tcx>) -> NormalizingClosureTyper<'a,'tcx> { - // Parameter environment is used to give details about type parameters, - // but since we are in trans, everything is fully monomorphized. - NormalizingClosureTyper { param_env: tcx.empty_parameter_environment() } - } -} - -impl<'a,'tcx> ty::ClosureTyper<'tcx> for NormalizingClosureTyper<'a,'tcx> { - fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> { - &self.param_env - } - - fn closure_kind(&self, - def_id: ast::DefId) - -> Option - { - self.param_env.closure_kind(def_id) - } - - fn closure_type(&self, - def_id: ast::DefId, - substs: &subst::Substs<'tcx>) - -> ty::ClosureTy<'tcx> - { - // the substitutions in `substs` are already monomorphized, - // but we still must normalize associated types - let closure_ty = self.param_env.tcx.closure_type(def_id, substs); - monomorphize::normalize_associated_type(self.param_env.tcx, &closure_ty) - } - - fn closure_upvars(&self, - def_id: ast::DefId, - substs: &Substs<'tcx>) - -> Option>> - { - // the substitutions in `substs` are already monomorphized, - // but we still must normalize associated types - let result = self.param_env.closure_upvars(def_id, substs); - monomorphize::normalize_associated_type(self.param_env.tcx, &result) - } -} - pub fn drain_fulfillment_cx_or_panic<'a,'tcx,T>(span: Span, infcx: &infer::InferCtxt<'a,'tcx>, fulfill_cx: &mut traits::FulfillmentContext<'tcx>, @@ -1120,12 +1069,12 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &infer::InferCtxt<'a,'tcx>, { debug!("drain_fulfillment_cx(result={:?})", result); - + // this is stupid but temporary + let typer: &ClosureTyper<'tcx> = infcx; // In principle, we only need to do this so long as `result` // contains unbound type parameters. It could be a slight // optimization to stop iterating early. - let typer = NormalizingClosureTyper::new(infcx.tcx); - match fulfill_cx.select_all_or_error(infcx, &typer) { + match fulfill_cx.select_all_or_error(infcx, typer) { Ok(()) => { } Err(errors) => { return Err(errors); diff --git a/src/librustc_trans/trans/debuginfo/metadata.rs b/src/librustc_trans/trans/debuginfo/metadata.rs index 1fbbf0763aa..12892c87b46 100644 --- a/src/librustc_trans/trans/debuginfo/metadata.rs +++ b/src/librustc_trans/trans/debuginfo/metadata.rs @@ -26,9 +26,10 @@ use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType}; use metadata::csearch; use middle::pat_util; use middle::subst::{self, Substs}; +use middle::infer; use rustc::ast_map; use trans::{type_of, adt, machine, monomorphize}; -use trans::common::{self, CrateContext, FunctionContext, NormalizingClosureTyper, Block}; +use trans::common::{self, CrateContext, FunctionContext, Block}; use trans::_match::{BindingInfo, TrByCopy, TrByMove, TrByRef}; use trans::type_::Type; use middle::ty::{self, Ty, ClosureTyper}; @@ -287,8 +288,8 @@ impl<'tcx> TypeMap<'tcx> { } }, ty::TyClosure(def_id, substs) => { - let typer = NormalizingClosureTyper::new(cx.tcx()); - let closure_ty = typer.closure_type(def_id, substs); + let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables); + let closure_ty = infcx.closure_type(def_id, substs); self.get_unique_type_id_of_closure_type(cx, closure_ty, &mut unique_type_id); @@ -796,8 +797,8 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, subroutine_type_metadata(cx, unique_type_id, &barefnty.sig, usage_site_span) } ty::TyClosure(def_id, substs) => { - let typer = NormalizingClosureTyper::new(cx.tcx()); - let sig = typer.closure_type(def_id, substs).sig; + let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables); + let sig = infcx.closure_type(def_id, substs).sig; subroutine_type_metadata(cx, unique_type_id, &sig, usage_site_span) } ty::TyStruct(def_id, substs) => { diff --git a/src/librustc_trans/trans/declare.rs b/src/librustc_trans/trans/declare.rs index 646ca6733c3..0eaaaaa5b34 100644 --- a/src/librustc_trans/trans/declare.rs +++ b/src/librustc_trans/trans/declare.rs @@ -21,10 +21,10 @@ //! * When in doubt, define. use llvm::{self, ValueRef}; use middle::ty::{self, ClosureTyper}; +use middle::infer; use syntax::abi; use trans::attributes; use trans::base; -use trans::common; use trans::context::CrateContext; use trans::monomorphize; use trans::type_::Type; @@ -117,8 +117,8 @@ pub fn declare_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str, (&f.sig, f.abi, None) } ty::TyClosure(closure_did, substs) => { - let typer = common::NormalizingClosureTyper::new(ccx.tcx()); - function_type = typer.closure_type(closure_did, substs); + let infcx = infer::normalizing_infer_ctxt(ccx.tcx(), &ccx.tcx().tables); + function_type = infcx.closure_type(closure_did, substs); let self_type = base::self_type_for_closure(ccx, closure_did, fn_type); let llenvironment_type = type_of::type_of_explicit_arg(ccx, self_type); debug!("declare_rust_fn function_type={:?} self_type={:?}", diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index b88251c69a0..b297a731d29 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -324,9 +324,8 @@ 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, true); - let typer = NormalizingClosureTyper::new(tcx); - let mut selcx = traits::SelectionContext::new(&infcx, &typer); + let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables); + let mut selcx = traits::SelectionContext::new(&infcx, &infcx); let cause = traits::ObligationCause::dummy(); let traits::Normalized { value: result, obligations } = traits::normalize(&mut selcx, cause, &value); @@ -336,7 +335,7 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T obligations); let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); - + for obligation in obligations { fulfill_cx.register_predicate_obligation(&infcx, obligation); } From e2d7e904ca621b72a7445e666baba4b282d2bb7d Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Sun, 28 Jun 2015 23:03:47 -0700 Subject: [PATCH 05/10] Remove Typer + ClosureTyper impls for ParameterEnv --- src/librustc/middle/check_const.rs | 9 +- src/librustc/middle/check_match.rs | 10 +- src/librustc/middle/check_rvalues.rs | 7 +- src/librustc/middle/const_eval.rs | 2 +- src/librustc/middle/infer/mod.rs | 2 +- src/librustc/middle/traits/coherence.rs | 3 +- src/librustc/middle/traits/mod.rs | 2 +- src/librustc/middle/ty.rs | 91 +++---------------- src/librustc_borrowck/borrowck/check_loans.rs | 6 +- .../borrowck/gather_loans/mod.rs | 9 +- src/librustc_borrowck/borrowck/mod.rs | 2 +- src/librustc_lint/builtin.rs | 4 +- src/librustc_trans/trans/_match.rs | 3 +- src/librustc_trans/trans/common.rs | 4 +- src/librustc_trans/trans/datum.rs | 5 +- src/librustc_typeck/check/compare_method.rs | 12 +-- src/librustc_typeck/check/mod.rs | 4 +- src/librustc_typeck/coherence/mod.rs | 2 +- 18 files changed, 60 insertions(+), 117 deletions(-) diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 95a598ad115..139750af628 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -111,13 +111,16 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { fn with_euv<'b, F, R>(&'b mut self, item_id: Option, f: F) -> R where F: for<'t> FnOnce(&mut euv::ExprUseVisitor<'b, 't, 'tcx, - ty::ParameterEnvironment<'a, 'tcx>>) -> R, + infer::InferCtxt<'a, 'tcx>>) -> R, { let param_env = match item_id { Some(item_id) => ty::ParameterEnvironment::for_item(self.tcx, item_id), None => self.tcx.empty_parameter_environment() }; - f(&mut euv::ExprUseVisitor::new(self, ¶m_env)) + + let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, Some(param_env), false); + + f(&mut euv::ExprUseVisitor::new(self, &infcx)) } fn global_expr(&mut self, mode: Mode, expr: &ast::Expr) -> ConstQualif { @@ -287,7 +290,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic); let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause); - match fulfill_cx.select_all_or_error(&infcx, &infcx.parameter_environment) { + match fulfill_cx.select_all_or_error(&infcx, &infcx) { Ok(()) => { }, Err(ref errors) => { traits::report_fulfillment_errors(&infcx, errors); diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index f61884e2136..900a231835e 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -20,6 +20,7 @@ use middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, Init}; use middle::expr_use_visitor::{JustWrite, LoanCause, MutateMode}; use middle::expr_use_visitor::WriteAndRead; use middle::expr_use_visitor as euv; +use middle::infer; use middle::mem_categorization::{cmt, Typer}; use middle::pat_util::*; use middle::ty::*; @@ -1111,7 +1112,9 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt, match p.node { ast::PatIdent(ast::BindByValue(_), _, ref sub) => { let pat_ty = tcx.node_id_to_type(p.id); - if cx.param_env.type_moves_by_default(pat_ty, pat.span) { + //FIXME: (@jroesch) this code should be floated up as well + let infcx = infer::new_infer_ctxt(cx.tcx, &cx.tcx.tables, Some(cx.param_env.clone()), false); + if infcx.type_moves_by_default(pat_ty, pat.span) { check_move(p, sub.as_ref().map(|p| &**p)); } } @@ -1139,8 +1142,9 @@ fn check_for_mutation_in_guard<'a, 'tcx>(cx: &'a MatchCheckCtxt<'a, 'tcx>, let mut checker = MutationChecker { cx: cx, }; - let mut visitor = ExprUseVisitor::new(&mut checker, - &checker.cx.param_env); + + let infcx = infer::new_infer_ctxt(cx.tcx, &cx.tcx.tables, Some(checker.cx.param_env.clone()), false); + let mut visitor = ExprUseVisitor::new(&mut checker, &infcx); visitor.walk_expr(guard); } diff --git a/src/librustc/middle/check_rvalues.rs b/src/librustc/middle/check_rvalues.rs index 1489e946fe2..23accf88dc9 100644 --- a/src/librustc/middle/check_rvalues.rs +++ b/src/librustc/middle/check_rvalues.rs @@ -12,6 +12,7 @@ // is the public starting point. use middle::expr_use_visitor as euv; +use middle::infer; use middle::mem_categorization as mc; use middle::ty::ParameterEnvironment; use middle::ty; @@ -38,9 +39,11 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for RvalueContext<'a, 'tcx> { s: Span, fn_id: ast::NodeId) { { + // FIXME (@jroesch) change this to be an inference context let param_env = ParameterEnvironment::for_item(self.tcx, fn_id); - let mut delegate = RvalueContextDelegate { tcx: self.tcx, param_env: ¶m_env }; - let mut euv = euv::ExprUseVisitor::new(&mut delegate, ¶m_env); + let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, Some(param_env), false); + let mut delegate = RvalueContextDelegate { tcx: self.tcx, param_env: &infcx.parameter_environment }; + let mut euv = euv::ExprUseVisitor::new(&mut delegate, &infcx); euv.walk_fn(fd, b); } visit::walk_fn(self, fk, fd, b, s) diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 7d4553c8b14..b98864304d2 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -1033,7 +1033,7 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>, tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id()); let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false); - let mut selcx = traits::SelectionContext::new(&infcx, &infcx.parameter_environment); + let mut selcx = traits::SelectionContext::new(&infcx, &infcx); let obligation = traits::Obligation::new(traits::ObligationCause::dummy(), trait_ref.to_poly_trait_predicate()); let selection = match selcx.select(&obligation) { diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 91fee77f0a7..31bfc01886c 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -525,7 +525,7 @@ impl<'a, 'tcx> mc::Typer<'tcx> for InferCtxt<'a, 'tcx> { } fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option { - self.parameter_environment.temporary_scope(rvalue_id) + self.tcx.region_maps.temporary_scope(rvalue_id) } fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option { diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs index 371b5c309a8..25b336f0c7a 100644 --- a/src/librustc/middle/traits/coherence.rs +++ b/src/librustc/middle/traits/coherence.rs @@ -38,8 +38,7 @@ pub fn overlapping_impls(infcx: &InferCtxt, impl1_def_id, impl2_def_id); - let param_env = &infcx.tcx.empty_parameter_environment(); - let selcx = &mut SelectionContext::intercrate(infcx, param_env); + let selcx = &mut SelectionContext::intercrate(infcx, infcx); infcx.probe(|_| { overlap(selcx, impl1_def_id, impl2_def_id) || overlap(selcx, impl2_def_id, impl1_def_id) }) diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index c398a24f4f6..8c065e182cd 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -398,7 +398,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), false); - let predicates = match fully_normalize(&infcx, &infcx.parameter_environment, cause, + let predicates = match fully_normalize(&infcx, &infcx, cause, &infcx.parameter_environment.caller_bounds) { Ok(predicates) => predicates, Err(errors) => { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 8e5b6f4d450..23aa840703b 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -52,7 +52,6 @@ use middle::dependency_format; use middle::fast_reject; use middle::free_region::FreeRegionMap; use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; -use middle::mem_categorization as mc; use middle::mem_categorization::Typer; use middle::region; use middle::resolve_lifetime; @@ -2919,11 +2918,14 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> { -> Result<(),CopyImplementationError> { let tcx = self.tcx; + // FIXME: (@jroesch) float this code up + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(self.clone()), false); + let did = match self_type.sty { ty::TyStruct(struct_did, substs) => { let fields = tcx.struct_fields(struct_did, substs); for field in &fields { - if self.type_moves_by_default(field.mt.ty, span) { + if infcx.type_moves_by_default(field.mt.ty, span) { return Err(FieldDoesNotImplementCopy(field.name)) } } @@ -2935,7 +2937,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> { for variant_arg_type in &variant.args { let substd_arg_type = variant_arg_type.subst(tcx, substs); - if self.type_moves_by_default(substd_arg_type, span) { + if infcx.type_moves_by_default(substd_arg_type, span) { return Err(VariantDoesNotImplementCopy(variant.name)) } } @@ -4272,7 +4274,8 @@ impl<'tcx> TyS<'tcx> { TyClosure(did, substs) => { // FIXME(#14449): `borrowed_contents` below assumes `&mut` closure. let param_env = cx.empty_parameter_environment(); - let upvars = param_env.closure_upvars(did, substs).unwrap(); + let infcx = infer::new_infer_ctxt(cx, &cx.tables, Some(param_env), false); + let upvars = infcx.closure_upvars(did, substs).unwrap(); TypeContents::union(&upvars, |f| tc_ty(cx, &f.ty, cache)) } @@ -4400,10 +4403,10 @@ impl<'tcx> TyS<'tcx> { span: Span) -> bool { - let tcx = param_env.tcx(); + let tcx = param_env.tcx; let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(param_env.clone()), false); - let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, param_env, + let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, &infcx, self, bound, span); debug!("Ty::impls_bound({:?}, {:?}) = {:?}", @@ -4412,7 +4415,8 @@ impl<'tcx> TyS<'tcx> { is_impld } - fn moves_by_default<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>, + // temp hack, probably should be private + pub fn moves_by_default<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>, span: Span) -> bool { if self.flags.get().intersects(TypeFlags::MOVENESS_CACHED) { return self.flags.get().intersects(TypeFlags::MOVES_BY_DEFAULT); @@ -6711,79 +6715,6 @@ impl<'tcx> ctxt<'tcx> { } } -impl<'a,'tcx> Typer<'tcx> for ParameterEnvironment<'a,'tcx> { - fn node_ty(&self, id: ast::NodeId) -> mc::McResult> { - Ok(self.tcx.node_id_to_type(id)) - } - - fn expr_ty_adjusted(&self, expr: &ast::Expr) -> mc::McResult> { - Ok(self.tcx.expr_ty_adjusted(expr)) - } - - fn node_method_ty(&self, method_call: ty::MethodCall) -> Option> { - self.tcx.tables.borrow().method_map.get(&method_call).map(|method| method.ty) - } - - fn node_method_origin(&self, method_call: ty::MethodCall) - -> Option> - { - self.tcx.tables.borrow().method_map.get(&method_call).map(|method| method.origin.clone()) - } - - fn adjustments(&self) -> Ref>> { - fn projection<'a, 'tcx>(tables: &'a Tables<'tcx>) -> &'a NodeMap> { - &tables.adjustments - } - - Ref::map(self.tcx.tables.borrow(), projection) - } - - fn is_method_call(&self, id: ast::NodeId) -> bool { - self.tcx.is_method_call(id) - } - - fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option { - self.tcx.region_maps.temporary_scope(rvalue_id) - } - - fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option { - self.tcx.upvar_capture(upvar_id) - } - - fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool { - ty.moves_by_default(self, span) - } -} - -impl<'a,'tcx> ClosureTyper<'tcx> for ty::ParameterEnvironment<'a,'tcx> { - fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> { - self - } - - fn closure_kind(&self, - def_id: ast::DefId) - -> Option - { - Some(self.tcx.closure_kind(def_id)) - } - - fn closure_type(&self, - def_id: ast::DefId, - substs: &subst::Substs<'tcx>) - -> ty::ClosureTy<'tcx> - { - self.tcx.closure_type(def_id, substs) - } - - fn closure_upvars(&self, - def_id: ast::DefId, - substs: &Substs<'tcx>) - -> Option>> { - ctxt::closure_upvars(self, def_id, substs) - } -} - - /// The category of explicit self. #[derive(Clone, Copy, Eq, PartialEq, Debug)] pub enum ExplicitSelfCategory { diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index 9d4fb4c994d..7c2318eef9c 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -21,6 +21,7 @@ use self::UseError::*; use borrowck::*; use borrowck::InteriorKind::{InteriorElement, InteriorField}; use rustc::middle::expr_use_visitor as euv; +use rustc::middle::infer; use rustc::middle::mem_categorization as mc; use rustc::middle::region; use rustc::middle::ty; @@ -198,17 +199,18 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, debug!("check_loans(body id={})", body.id); let param_env = ty::ParameterEnvironment::for_item(bccx.tcx, fn_id); + let infcx = infer::new_infer_ctxt(bccx.tcx, &bccx.tcx.tables, Some(param_env), false); let mut clcx = CheckLoanCtxt { bccx: bccx, dfcx_loans: dfcx_loans, move_data: move_data, all_loans: all_loans, - param_env: ¶m_env, + param_env: &infcx.parameter_environment }; { - let mut euv = euv::ExprUseVisitor::new(&mut clcx, ¶m_env); + let mut euv = euv::ExprUseVisitor::new(&mut clcx, &infcx); euv.walk_fn(decl, body); } } diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 44a4a0d2504..432d6289efe 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -19,6 +19,7 @@ use borrowck::*; use borrowck::move_data::MoveData; use rustc::middle::expr_use_visitor as euv; +use rustc::middle::infer; use rustc::middle::mem_categorization as mc; use rustc::middle::region; use rustc::middle::ty; @@ -49,9 +50,9 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, }; let param_env = ty::ParameterEnvironment::for_item(bccx.tcx, fn_id); - + let infcx = infer::new_infer_ctxt(bccx.tcx, &bccx.tcx.tables, Some(param_env), false); { - let mut euv = euv::ExprUseVisitor::new(&mut glcx, ¶m_env); + let mut euv = euv::ExprUseVisitor::new(&mut glcx, &infcx); euv.walk_fn(decl, body); } @@ -490,8 +491,8 @@ struct StaticInitializerCtxt<'a, 'tcx: 'a> { impl<'a, 'tcx, 'v> Visitor<'v> for StaticInitializerCtxt<'a, 'tcx> { fn visit_expr(&mut self, ex: &Expr) { if let ast::ExprAddrOf(mutbl, ref base) = ex.node { - let param_env = self.bccx.tcx.empty_parameter_environment(); - let mc = mc::MemCategorizationContext::new(¶m_env); + let infcx = infer::new_infer_ctxt(self.bccx.tcx, &self.bccx.tcx.tables, None, false); + let mc = mc::MemCategorizationContext::new(&infcx); let base_cmt = mc.cat_expr(&**base).unwrap(); let borrow_kind = ty::BorrowKind::from_mutbl(mutbl); // Check that we don't allow borrows of unsafe static items. diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 4f726044a1b..3cf2a62b3b6 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -747,7 +747,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { -> (&'static str, &'static str) { match ty.sty { _ => { - if param_env.type_moves_by_default(ty, span) { + if ty.moves_by_default(param_env, span) { ("non-copyable", "perhaps you meant to use `clone()`?") } else { diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 190e2965e76..5661109ab45 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1704,7 +1704,9 @@ impl LintPass for MissingCopyImplementations { _ => return, }; let parameter_environment = cx.tcx.empty_parameter_environment(); - if !parameter_environment.type_moves_by_default(ty, item.span) { + // FIXME (@jroesch) should probably inver this so that the parameter env still impls this + // method + if !ty.moves_by_default(¶meter_environment, item.span) { return; } if parameter_environment.can_type_implement_copy(ty, item.span).is_ok() { diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index 47c2a5e579d..9b293f7b1a7 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -197,7 +197,6 @@ use middle::def::{self, DefMap}; use middle::expr_use_visitor as euv; use middle::lang_items::StrEqFnLangItem; use middle::mem_categorization as mc; -use middle::mem_categorization::Typer; use middle::pat_util::*; use trans::adt; use trans::base::*; @@ -1416,7 +1415,7 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &ast::Pat, let trmode; match bm { ast::BindByValue(_) - if !param_env.type_moves_by_default(variable_ty, span) || reassigned => + if !variable_ty.moves_by_default(¶m_env, span) || reassigned => { llmatch = alloca_no_lifetime(bcx, llvariable_ty.ptr_to(), diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 1fc68790db0..d4f318a4258 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -154,7 +154,7 @@ fn type_needs_drop_given_env<'a,'tcx>(cx: &ty::ctxt<'tcx>, // normalized version of the type, and therefore will definitely // know whether the type implements Copy (and thus needs no // cleanup/drop/zeroing) ... - let implements_copy = !param_env.type_moves_by_default(ty, DUMMY_SP); + let implements_copy = !ty.moves_by_default(param_env, DUMMY_SP); if implements_copy { return false; } @@ -630,7 +630,7 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> { } fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool { - self.fcx.param_env.type_moves_by_default(ty, span) + ty.moves_by_default(&self.fcx.param_env, span) } } diff --git a/src/librustc_trans/trans/datum.rs b/src/librustc_trans/trans/datum.rs index 2c539b67cb6..c0ebffb58af 100644 --- a/src/librustc_trans/trans/datum.rs +++ b/src/librustc_trans/trans/datum.rs @@ -101,7 +101,6 @@ use trans::cleanup::CleanupMethods; use trans::expr; use trans::tvec; use trans::type_of; -use middle::mem_categorization::Typer; use middle::ty::Ty; use std::fmt; @@ -606,8 +605,8 @@ impl<'tcx, K: KindOps + fmt::Debug> Datum<'tcx, K> { * affine values (since they must never be duplicated). */ - assert!(!bcx.tcx().empty_parameter_environment() - .type_moves_by_default(self.ty, DUMMY_SP)); + assert!(!self.ty + .moves_by_default(&bcx.tcx().empty_parameter_environment(), DUMMY_SP)); self.shallow_copy_raw(bcx, dst) } diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 85478945e1c..c05b95f4aeb 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -246,7 +246,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, debug!("compare_impl_method: trait_bounds={:?}", infcx.parameter_environment.caller_bounds); - let mut selcx = traits::SelectionContext::new(&infcx, &infcx.parameter_environment); + let mut selcx = traits::SelectionContext::new(&infcx, &infcx); for predicate in impl_pred.fns { let traits::Normalized { value: predicate, .. } = @@ -293,7 +293,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, impl_sig.subst(tcx, impl_to_skol_substs); let impl_sig = assoc::normalize_associated_types_in(&infcx, - &impl_param_env, + &infcx, &mut fulfillment_cx, impl_m_span, impl_m_body_id, @@ -312,7 +312,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, trait_sig.subst(tcx, &trait_to_skol_substs); let trait_sig = assoc::normalize_associated_types_in(&infcx, - &impl_param_env, + &infcx, &mut fulfillment_cx, impl_m_span, impl_m_body_id, @@ -347,7 +347,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, // Check that all obligations are satisfied by the implementation's // version. - match fulfillment_cx.select_all_or_error(&infcx, &infcx.parameter_environment) { + match fulfillment_cx.select_all_or_error(&infcx, &infcx) { Err(ref errors) => { traits::report_fulfillment_errors(&infcx, errors) } Ok(_) => {} } @@ -456,7 +456,7 @@ pub fn compare_const_impl<'tcx>(tcx: &ty::ctxt<'tcx>, // There is no "body" here, so just pass dummy id. let impl_ty = assoc::normalize_associated_types_in(&infcx, - &impl_param_env, + &infcx, &mut fulfillment_cx, impl_c_span, 0, @@ -466,7 +466,7 @@ pub fn compare_const_impl<'tcx>(tcx: &ty::ctxt<'tcx>, let trait_ty = assoc::normalize_associated_types_in(&infcx, - &impl_param_env, + &infcx, &mut fulfillment_cx, impl_c_span, 0, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 806bcb2306b..4d750f88093 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -431,7 +431,7 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, ccx.tcx.liberate_late_bound_regions(region::DestructionScopeData::new(body.id), &fn_sig); let fn_sig = - inh.normalize_associated_types_in(&inh.infcx.parameter_environment, + inh.normalize_associated_types_in(&inh.infcx, body.span, body.id, &fn_sig); @@ -1504,7 +1504,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { -> bool { traits::type_known_to_meet_builtin_bound(self.infcx(), - self.param_env(), + self.infcx(), ty, ty::BoundSized, span) diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 1219f2928c1..0650f7deb06 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -541,7 +541,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { // Check that all transitive obligations are satisfied. if let Err(errors) = fulfill_cx.select_all_or_error(&infcx, - &infcx.parameter_environment) { + &infcx) { traits::report_fulfillment_errors(&infcx, &errors); } From 05c57e0e6a667422c8a9159febbf0476f039f4fc Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Mon, 29 Jun 2015 17:46:24 -0700 Subject: [PATCH 06/10] Remove Typer + ClosureTyper impls for BlockS --- src/librustc/middle/check_const.rs | 3 +- src/librustc/middle/check_rvalues.rs | 4 +- src/librustc/middle/expr_use_visitor.rs | 15 ++-- src/librustc/middle/infer/mod.rs | 6 +- src/librustc/middle/mem_categorization.rs | 26 +++---- src/librustc_trans/lib.rs | 1 - src/librustc_trans/trans/_match.rs | 4 +- src/librustc_trans/trans/common.rs | 92 +---------------------- src/librustc_typeck/check/regionck.rs | 4 +- 9 files changed, 32 insertions(+), 123 deletions(-) diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 139750af628..2798cfa43dd 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -110,8 +110,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { } fn with_euv<'b, F, R>(&'b mut self, item_id: Option, f: F) -> R where - F: for<'t> FnOnce(&mut euv::ExprUseVisitor<'b, 't, 'tcx, - infer::InferCtxt<'a, 'tcx>>) -> R, + F: for<'t> FnOnce(&mut euv::ExprUseVisitor<'b, 't, 'b, 'tcx>) -> R, { let param_env = match item_id { Some(item_id) => ty::ParameterEnvironment::for_item(self.tcx, item_id), diff --git a/src/librustc/middle/check_rvalues.rs b/src/librustc/middle/check_rvalues.rs index 23accf88dc9..731e49192a8 100644 --- a/src/librustc/middle/check_rvalues.rs +++ b/src/librustc/middle/check_rvalues.rs @@ -41,8 +41,8 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for RvalueContext<'a, 'tcx> { { // FIXME (@jroesch) change this to be an inference context let param_env = ParameterEnvironment::for_item(self.tcx, fn_id); - let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, Some(param_env), false); - let mut delegate = RvalueContextDelegate { tcx: self.tcx, param_env: &infcx.parameter_environment }; + let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, Some(param_env.clone()), false); + let mut delegate = RvalueContextDelegate { tcx: self.tcx, param_env: ¶m_env }; let mut euv = euv::ExprUseVisitor::new(&mut delegate, &infcx); euv.walk_fn(fd, b); } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 25728c50c61..c8555d28e40 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -21,9 +21,10 @@ use self::TrackMatchMode::*; use self::OverloadedCallType::*; use middle::{def, region, pat_util}; +use middle::infer; use middle::mem_categorization as mc; use middle::mem_categorization::Typer; -use middle::ty::{self}; +use middle::ty::{self, ClosureTyper}; use middle::ty::{MethodCall, MethodObject, MethodTraitObject}; use middle::ty::{MethodOrigin, MethodParam, MethodTypeParam}; use middle::ty::{MethodStatic, MethodStaticClosure}; @@ -291,9 +292,9 @@ impl OverloadedCallType { // supplies types from the tree. After type checking is complete, you // can just use the tcx as the typer. -pub struct ExprUseVisitor<'d,'t,'tcx:'t,TYPER:'t> { - typer: &'t TYPER, - mc: mc::MemCategorizationContext<'t,TYPER>, +pub struct ExprUseVisitor<'d,'t,'a: 't, 'tcx:'a> { + typer: &'t infer::InferCtxt<'a, 'tcx>, + mc: mc::MemCategorizationContext<'t, 'a, 'tcx>, delegate: &'d mut (Delegate<'tcx>+'d), } @@ -319,10 +320,10 @@ enum PassArgs { ByRef, } -impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { +impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { pub fn new(delegate: &'d mut Delegate<'tcx>, - typer: &'t TYPER) - -> ExprUseVisitor<'d,'t,'tcx,TYPER> { + typer: &'t infer::InferCtxt<'a, 'tcx>) + -> ExprUseVisitor<'d,'t,'a, 'tcx> { ExprUseVisitor { typer: typer, mc: mc::MemCategorizationContext::new(typer), diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 31bfc01886c..6ca1c22a2c2 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -30,7 +30,7 @@ use middle::region::CodeExtent; use middle::subst; use middle::subst::Substs; use middle::subst::Subst; -use middle::traits::{self, FulfillmentContext, Normalized, MiscObligation, +use middle::traits::{self, FulfillmentContext, Normalized, SelectionContext, ObligationCause}; use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, UnconstrainedNumeric}; use middle::ty::{self, Ty, HasTypeFlags}; @@ -477,7 +477,7 @@ pub struct CombinedSnapshot { impl<'a, 'tcx> mc::Typer<'tcx> for InferCtxt<'a, 'tcx> { fn node_ty(&self, id: ast::NodeId) -> McResult> { - let ty = self.node_ty(id); + let ty = self.node_type(id); self.resolve_type_vars_or_error(&ty) } @@ -1183,7 +1183,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .map(|method| resolve_ty(method.ty))) } - pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> { + pub fn node_type(&self, id: ast::NodeId) -> Ty<'tcx> { match self.tables.borrow().node_types.get(&id) { Some(&t) => t, // FIXME diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 13e127e9126..867174ffbc5 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -73,10 +73,11 @@ pub use self::categorization::*; use self::Aliasability::*; use ast_map; +use middle::infer; use middle::check_const; use middle::def; use middle::region; -use middle::ty::{self, Ty}; +use middle::ty::{self, Ty, ClosureTyper}; use util::nodemap::NodeMap; use syntax::ast::{MutImmutable, MutMutable}; @@ -255,13 +256,10 @@ impl ast_node for ast::Pat { fn span(&self) -> Span { self.span } } -pub struct MemCategorizationContext<'t,TYPER:'t> { - typer: &'t TYPER -} - -impl<'t,TYPER:'t> Copy for MemCategorizationContext<'t,TYPER> {} -impl<'t,TYPER:'t> Clone for MemCategorizationContext<'t,TYPER> { - fn clone(&self) -> MemCategorizationContext<'t,TYPER> { *self } +#[derive(Copy, Clone)] +pub struct MemCategorizationContext<'t, 'a: 't, 'tcx : 'a> { + pub typer: &'t infer::InferCtxt<'a, 'tcx>, + // pub monomorphize: bool, } pub type McResult = Result; @@ -391,13 +389,13 @@ impl MutabilityCategory { } } -impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { - pub fn new(typer: &'t TYPER) -> MemCategorizationContext<'t,TYPER> { +impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> { + pub fn new(typer: &'t infer::InferCtxt<'a, 'tcx>) -> MemCategorizationContext<'t, 'a, 'tcx> { MemCategorizationContext { typer: typer } } - fn tcx(&self) -> &'t ty::ctxt<'tcx> { - self.typer.tcx() + fn tcx(&self) -> &'a ty::ctxt<'tcx> { + self.typer.tcx } fn expr_ty(&self, expr: &ast::Expr) -> McResult> { @@ -1175,7 +1173,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { } pub fn cat_pattern(&self, cmt: cmt<'tcx>, pat: &ast::Pat, mut op: F) -> McResult<()> - where F: FnMut(&MemCategorizationContext<'t, TYPER>, cmt<'tcx>, &ast::Pat), + where F: FnMut(&MemCategorizationContext<'t, 'a, 'tcx>, cmt<'tcx>, &ast::Pat), { self.cat_pattern_(cmt, pat, &mut op) } @@ -1183,7 +1181,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { // FIXME(#19596) This is a workaround, but there should be a better way to do this fn cat_pattern_(&self, cmt: cmt<'tcx>, pat: &ast::Pat, op: &mut F) -> McResult<()> - where F : FnMut(&MemCategorizationContext<'t, TYPER>, cmt<'tcx>, &ast::Pat), + where F : FnMut(&MemCategorizationContext<'t, 'a, 'tcx>, cmt<'tcx>, &ast::Pat), { // Here, `cmt` is the categorization for the value being // matched and pat is the pattern it is being matched against. diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index dc692b0e765..bb7e95cd4ae 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -43,7 +43,6 @@ #![feature(unicode)] #![feature(unicode)] #![feature(vec_push_all)] -#![feature(cell_extras)] #![allow(trivial_casts)] diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index 9b293f7b1a7..a9617bd17c0 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -195,6 +195,7 @@ use middle::check_match; use middle::const_eval; use middle::def::{self, DefMap}; use middle::expr_use_visitor as euv; +use middle::infer; use middle::lang_items::StrEqFnLangItem; use middle::mem_categorization as mc; use middle::pat_util::*; @@ -1350,7 +1351,8 @@ fn is_discr_reassigned(bcx: Block, discr: &ast::Expr, body: &ast::Expr) -> bool reassigned: false }; { - let mut visitor = euv::ExprUseVisitor::new(&mut rc, bcx); + let infcx = infer::new_infer_ctxt(bcx.tcx(), &bcx.tcx().tables, None, false); + let mut visitor = euv::ExprUseVisitor::new(&mut rc, &infcx); visitor.walk_expr(body); } rc.reassigned diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index d4f318a4258..598029b842b 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -22,7 +22,6 @@ use middle::cfg; use middle::def; use middle::infer; use middle::lang_items::LangItem; -use middle::mem_categorization as mc; use middle::mem_categorization::Typer; use middle::ty::ClosureTyper; use middle::region; @@ -48,7 +47,7 @@ use util::nodemap::{FnvHashMap, NodeMap}; use arena::TypedArena; use libc::{c_uint, c_char}; use std::ffi::CString; -use std::cell::{Cell, RefCell, Ref}; +use std::cell::{Cell, RefCell}; use std::result::Result as StdResult; use std::vec::Vec; use syntax::ast; @@ -577,95 +576,6 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> { } } -impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> { - fn node_ty(&self, id: ast::NodeId) -> mc::McResult> { - Ok(node_id_type(self, id)) - } - - fn expr_ty_adjusted(&self, expr: &ast::Expr) -> mc::McResult> { - Ok(expr_ty_adjusted(self, expr)) - } - - fn node_method_ty(&self, method_call: ty::MethodCall) -> Option> { - self.tcx() - .tables - .borrow() - .method_map - .get(&method_call) - .map(|method| monomorphize_type(self, method.ty)) - } - - fn node_method_origin(&self, method_call: ty::MethodCall) - -> Option> - { - self.tcx() - .tables - .borrow() - .method_map - .get(&method_call) - .map(|method| method.origin.clone()) - } - - fn adjustments<'a>(&'a self) -> Ref>> { - // FIXME (@jroesch): this is becuase we currently have a HR inference problem - // in the snapshot that causes this code not to work. - fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) -> - &'a NodeMap> { - &tables.adjustments - } - - Ref::map(self.tcx().tables.borrow(), project_adjustments) - } - - fn is_method_call(&self, id: ast::NodeId) -> bool { - self.tcx().tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id)) - } - - fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option { - self.tcx().region_maps.temporary_scope(rvalue_id) - } - - fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option { - Some(self.tcx().tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone()) - } - - fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool { - ty.moves_by_default(&self.fcx.param_env, span) - } -} - -impl<'blk, 'tcx> ty::ClosureTyper<'tcx> for BlockS<'blk, 'tcx> { - fn param_env<'a>(&'a self) -> &'a ty::ParameterEnvironment<'a, 'tcx> { - &self.fcx.param_env - } - - fn closure_kind(&self, - def_id: ast::DefId) - -> Option - { - let infcx = infer::normalizing_infer_ctxt(self.tcx(), &self.tcx().tables); - infcx.closure_kind(def_id) - } - - fn closure_type(&self, - def_id: ast::DefId, - substs: &subst::Substs<'tcx>) - -> ty::ClosureTy<'tcx> - { - let infcx = infer::normalizing_infer_ctxt(self.tcx(), &self.tcx().tables); - infcx.closure_type(def_id, substs) - } - - fn closure_upvars(&self, - def_id: ast::DefId, - substs: &Substs<'tcx>) - -> Option>> - { - let infcx = infer::new_infer_ctxt(self.tcx(), &self.tcx().tables, None, true); - infcx.closure_upvars(def_id, substs) - } -} - pub struct Result<'blk, 'tcx: 'blk> { pub bcx: Block<'blk, 'tcx>, pub val: ValueRef diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 661e1856ce8..a98bcc247ed 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -1101,8 +1101,8 @@ fn link_fn_args(rcx: &Rcx, body_scope: CodeExtent, args: &[ast::Arg]) { /// Link lifetimes of any ref bindings in `root_pat` to the pointers found in the discriminant, if /// needed. -fn link_pattern<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>, - mc: mc::MemCategorizationContext>, +fn link_pattern<'t, 'a, 'tcx>(rcx: &Rcx<'a, 'tcx>, + mc: mc::MemCategorizationContext<'t, 'a, 'tcx>, discr_cmt: mc::cmt<'tcx>, root_pat: &ast::Pat) { debug!("link_pattern(discr_cmt={:?}, root_pat={:?})", From 9faae6a5ca1c5579a8185138b1e534285324db87 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Tue, 30 Jun 2015 02:18:03 -0700 Subject: [PATCH 07/10] Remove Typer and ClosureTyper This commit finalizes the work of the past commits by fully moving the fulfillment context into the InferCtxt, cleaning up related context interfaces, removing the Typer and ClosureTyper traits and cleaning up related intefaces --- src/librustc/middle/astencode.rs | 1 - src/librustc/middle/check_const.rs | 2 +- src/librustc/middle/check_match.rs | 2 +- src/librustc/middle/const_eval.rs | 2 +- src/librustc/middle/expr_use_visitor.rs | 13 +- src/librustc/middle/implicator.rs | 6 +- src/librustc/middle/infer/mod.rs | 250 +++++++++--------- src/librustc/middle/liveness.rs | 2 - src/librustc/middle/mem_categorization.rs | 33 +-- src/librustc/middle/traits/coherence.rs | 2 +- src/librustc/middle/traits/fulfill.rs | 18 +- src/librustc/middle/traits/mod.rs | 10 +- src/librustc/middle/traits/select.rs | 24 +- src/librustc/middle/ty.rs | 36 +-- src/librustc_borrowck/borrowck/mod.rs | 1 - src/librustc_lint/builtin.rs | 1 - src/librustc_trans/trans/adt.rs | 2 +- src/librustc_trans/trans/attributes.rs | 2 +- src/librustc_trans/trans/base.rs | 2 +- src/librustc_trans/trans/closure.rs | 3 +- src/librustc_trans/trans/common.rs | 11 +- src/librustc_trans/trans/debuginfo/gdb.rs | 1 - .../trans/debuginfo/metadata.rs | 2 +- src/librustc_trans/trans/debuginfo/mod.rs | 2 +- .../trans/debuginfo/namespace.rs | 1 - .../trans/debuginfo/type_names.rs | 3 +- src/librustc_trans/trans/declare.rs | 2 +- src/librustc_trans/trans/expr.rs | 1 - src/librustc_trans/trans/meth.rs | 1 - src/librustc_trans/trans/monomorphize.rs | 4 +- src/librustc_typeck/check/assoc.rs | 6 +- src/librustc_typeck/check/callee.rs | 2 +- src/librustc_typeck/check/coercion.rs | 2 +- src/librustc_typeck/check/compare_method.rs | 10 +- src/librustc_typeck/check/method/confirm.rs | 1 - src/librustc_typeck/check/method/mod.rs | 2 +- src/librustc_typeck/check/method/probe.rs | 6 +- src/librustc_typeck/check/method/suggest.rs | 2 +- src/librustc_typeck/check/mod.rs | 15 +- src/librustc_typeck/check/regionck.rs | 7 +- src/librustc_typeck/check/wf.rs | 2 +- src/librustc_typeck/coherence/mod.rs | 3 +- 42 files changed, 194 insertions(+), 304 deletions(-) diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index d2c79e1d820..ad87643e550 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -26,7 +26,6 @@ use metadata::tydecode::{RegionParameter, ClosureSource}; use metadata::tyencode; use middle::cast; use middle::check_const::ConstQualif; -use middle::mem_categorization::Typer; use middle::privacy::{AllPublic, LastMod}; use middle::subst; use middle::subst::VecPerParamSpace; diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 2798cfa43dd..19b688e5ccf 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -289,7 +289,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic); let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause); - match fulfill_cx.select_all_or_error(&infcx, &infcx) { + match fulfill_cx.select_all_or_error(&infcx) { Ok(()) => { }, Err(ref errors) => { traits::report_fulfillment_errors(&infcx, errors); diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 900a231835e..8e315901db2 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -21,7 +21,7 @@ use middle::expr_use_visitor::{JustWrite, LoanCause, MutateMode}; use middle::expr_use_visitor::WriteAndRead; use middle::expr_use_visitor as euv; use middle::infer; -use middle::mem_categorization::{cmt, Typer}; +use middle::mem_categorization::{cmt}; use middle::pat_util::*; use middle::ty::*; use middle::ty; diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index b98864304d2..7d54b8c284f 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -1033,7 +1033,7 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>, tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id()); let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false); - let mut selcx = traits::SelectionContext::new(&infcx, &infcx); + let mut selcx = traits::SelectionContext::new(&infcx); let obligation = traits::Obligation::new(traits::ObligationCause::dummy(), trait_ref.to_poly_trait_predicate()); let selection = match selcx.select(&obligation) { diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index c8555d28e40..3edf0490214 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -23,8 +23,7 @@ use self::OverloadedCallType::*; use middle::{def, region, pat_util}; use middle::infer; use middle::mem_categorization as mc; -use middle::mem_categorization::Typer; -use middle::ty::{self, ClosureTyper}; +use middle::ty::{self}; use middle::ty::{MethodCall, MethodObject, MethodTraitObject}; use middle::ty::{MethodOrigin, MethodParam, MethodTypeParam}; use middle::ty::{MethodStatic, MethodStaticClosure}; @@ -356,7 +355,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { } fn tcx(&self) -> &'t ty::ctxt<'tcx> { - self.typer.tcx() + self.typer.tcx } fn delegate_consume(&mut self, @@ -691,7 +690,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { match local.init { None => { let delegate = &mut self.delegate; - pat_util::pat_bindings(&self.typer.tcx().def_map, &*local.pat, + pat_util::pat_bindings(&self.typer.tcx.def_map, &*local.pat, |_, id, span, _| { delegate.decl_without_init(id, span); }) @@ -1053,7 +1052,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { let delegate = &mut self.delegate; return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |mc, cmt_pat, pat| { if pat_util::pat_is_binding(def_map, pat) { - let tcx = typer.tcx(); + let tcx = typer.tcx; debug!("binding cmt_pat={:?} pat={:?} match_mode={:?}", cmt_pat, @@ -1140,7 +1139,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { // the leaves of the pattern tree structure. return_if_err!(mc.cat_pattern(cmt_discr, pat, |mc, cmt_pat, pat| { let def_map = def_map.borrow(); - let tcx = typer.tcx(); + let tcx = typer.tcx; match pat.node { ast::PatEnum(_, _) | ast::PatQPath(..) | @@ -1279,7 +1278,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { } } -fn copy_or_move<'tcx>(typer: &mc::Typer<'tcx>, +fn copy_or_move<'a, 'tcx>(typer: &infer::InferCtxt<'a, 'tcx>, cmt: &mc::cmt<'tcx>, move_reason: MoveReason) -> ConsumeMode diff --git a/src/librustc/middle/implicator.rs b/src/librustc/middle/implicator.rs index d5fa885b16a..3e097578857 100644 --- a/src/librustc/middle/implicator.rs +++ b/src/librustc/middle/implicator.rs @@ -34,7 +34,6 @@ pub enum Implication<'tcx> { struct Implicator<'a, 'tcx: 'a> { infcx: &'a InferCtxt<'a,'tcx>, - closure_typer: &'a (ty::ClosureTyper<'tcx>+'a), body_id: ast::NodeId, stack: Vec<(ty::Region, Option>)>, span: Span, @@ -46,7 +45,6 @@ struct Implicator<'a, 'tcx: 'a> { /// appear in a context with lifetime `outer_region` pub fn implications<'a,'tcx>( infcx: &'a InferCtxt<'a,'tcx>, - closure_typer: &ty::ClosureTyper<'tcx>, body_id: ast::NodeId, ty: Ty<'tcx>, outer_region: ty::Region, @@ -60,8 +58,7 @@ pub fn implications<'a,'tcx>( let mut stack = Vec::new(); stack.push((outer_region, None)); - let mut wf = Implicator { closure_typer: closure_typer, - infcx: infcx, + let mut wf = Implicator { infcx: infcx, body_id: body_id, span: span, stack: stack, @@ -404,7 +401,6 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> { { let value = traits::fully_normalize(self.infcx, - self.closure_typer, traits::ObligationCause::misc(self.span, self.body_id), value); match value { diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 6ca1c22a2c2..a64fe8b9128 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -19,7 +19,6 @@ pub use self::TypeOrigin::*; pub use self::ValuePairs::*; pub use self::fixup_err::*; pub use middle::ty::IntVarValue; -use middle::ty::ClosureTyper; pub use self::freshen::TypeFreshener; pub use self::region_inference::GenericKind; @@ -475,129 +474,6 @@ pub struct CombinedSnapshot { region_vars_snapshot: RegionSnapshot, } -impl<'a, 'tcx> mc::Typer<'tcx> for InferCtxt<'a, 'tcx> { - fn node_ty(&self, id: ast::NodeId) -> McResult> { - let ty = self.node_type(id); - self.resolve_type_vars_or_error(&ty) - } - - fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult> { - let ty = self.adjust_expr_ty(expr, self.tables.borrow().adjustments.get(&expr.id)); - self.resolve_type_vars_or_error(&ty) - } - - fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool { - let ty = self.resolve_type_vars_if_possible(&ty); - !traits::type_known_to_meet_builtin_bound(self, self, ty, ty::BoundCopy, span) - } - - fn node_method_ty(&self, method_call: ty::MethodCall) - -> Option> { - self.tables - .borrow() - .method_map - .get(&method_call) - .map(|method| method.ty) - .map(|ty| self.resolve_type_vars_if_possible(&ty)) - } - - fn node_method_origin(&self, method_call: ty::MethodCall) - -> Option> - { - self.tables - .borrow() - .method_map - .get(&method_call) - .map(|method| method.origin.clone()) - } - - fn adjustments(&self) -> Ref>> { - fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) - -> &'a NodeMap> { - &tables.adjustments - } - - Ref::map(self.tables.borrow(), project_adjustments) - } - - fn is_method_call(&self, id: ast::NodeId) -> bool { - self.tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id)) - } - - fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option { - self.tcx.region_maps.temporary_scope(rvalue_id) - } - - fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option { - self.tables.borrow().upvar_capture_map.get(&upvar_id).cloned() - } -} - -impl<'a, 'tcx> ty::ClosureTyper<'tcx> for InferCtxt<'a, 'tcx> { - fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> { - &self.parameter_environment - } - - fn closure_kind(&self, - def_id: ast::DefId) - -> Option - { - self.tables.borrow().closure_kinds.get(&def_id).cloned() - } - - fn closure_type(&self, - def_id: ast::DefId, - substs: &subst::Substs<'tcx>) - -> ty::ClosureTy<'tcx> - { - - let closure_ty = self.tables - .borrow() - .closure_tys - .get(&def_id) - .unwrap() - .subst(self.tcx, substs); - - if self.normalize { - // NOTE: this flag is currently *always* set to false, we are slowly folding - // normalization into this trait and will come back to remove this in the near - // future. - - // code from NormalizingClosureTyper: - // the substitutions in `substs` are already monomorphized, - // but we still must normalize associated types - // normalize_associated_type(self.param_env.tcx, &closure_ty) - normalize_associated_type(&self.tcx, &closure_ty) - // panic!("see issue 26597: fufillment context refactor must occur") - } else { - closure_ty - } - } - - fn closure_upvars(&self, - def_id: ast::DefId, - substs: &Substs<'tcx>) - -> Option>> - { - let result = ty::ctxt::closure_upvars(self, def_id, substs); - - if self.normalize { - // NOTE: this flag is currently *always* set to false, we are slowly folding - // normalization into this trait and will come back to remove this in the near - // future. - - // code from NormalizingClosureTyper: - // the substitutions in `substs` are already monomorphized, - // but we still must normalize associated types - // monomorphize::normalize_associated_type(self.param_env.tcx, &result) - // panic!("see issue 26597: fufillment context refactor must occur") - normalize_associated_type(&self.tcx, &result) - } else { - result - } - } -} - pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T where T : TypeFoldable<'tcx> + HasTypeFlags { @@ -610,7 +486,7 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T } let infcx = new_infer_ctxt(tcx, &tcx.tables, None, true); - let mut selcx = traits::SelectionContext::new(&infcx, &infcx); + let mut selcx = traits::SelectionContext::new(&infcx); let cause = traits::ObligationCause::dummy(); let traits::Normalized { value: result, obligations } = traits::normalize(&mut selcx, cause, &value); @@ -663,12 +539,11 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, { debug!("drain_fulfillment_cx(result={:?})", result); - // this is stupid but temporary - let typer: &ClosureTyper<'tcx> = infcx; + // In principle, we only need to do this so long as `result` // contains unbound type parameters. It could be a slight // optimization to stop iterating early. - match fulfill_cx.select_all_or_error(infcx, typer) { + match fulfill_cx.select_all_or_error(infcx) { Ok(()) => { } Err(errors) => { return Err(errors); @@ -1429,6 +1304,125 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.equate(true, trace).relate(a, b) }).map(|_| ()) } + + pub fn node_ty(&self, id: ast::NodeId) -> McResult> { + let ty = self.node_type(id); + self.resolve_type_vars_or_error(&ty) + } + + pub fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult> { + let ty = self.adjust_expr_ty(expr, self.tables.borrow().adjustments.get(&expr.id)); + self.resolve_type_vars_or_error(&ty) + } + + pub fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool { + let ty = self.resolve_type_vars_if_possible(&ty); + !traits::type_known_to_meet_builtin_bound(self, ty, ty::BoundCopy, span) + } + + pub fn node_method_ty(&self, method_call: ty::MethodCall) + -> Option> { + self.tables + .borrow() + .method_map + .get(&method_call) + .map(|method| method.ty) + .map(|ty| self.resolve_type_vars_if_possible(&ty)) + } + + pub fn node_method_origin(&self, method_call: ty::MethodCall) + -> Option> + { + self.tables + .borrow() + .method_map + .get(&method_call) + .map(|method| method.origin.clone()) + } + + pub fn adjustments(&self) -> Ref>> { + fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) + -> &'a NodeMap> { + &tables.adjustments + } + + Ref::map(self.tables.borrow(), project_adjustments) + } + + pub fn is_method_call(&self, id: ast::NodeId) -> bool { + self.tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id)) + } + + pub fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option { + self.tcx.region_maps.temporary_scope(rvalue_id) + } + + pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option { + self.tables.borrow().upvar_capture_map.get(&upvar_id).cloned() + } + + pub fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> { + &self.parameter_environment + } + + pub fn closure_kind(&self, + def_id: ast::DefId) + -> Option + { + self.tables.borrow().closure_kinds.get(&def_id).cloned() + } + + pub fn closure_type(&self, + def_id: ast::DefId, + substs: &subst::Substs<'tcx>) + -> ty::ClosureTy<'tcx> + { + + let closure_ty = self.tables + .borrow() + .closure_tys + .get(&def_id) + .unwrap() + .subst(self.tcx, substs); + + if self.normalize { + // NOTE: this flag is currently *always* set to false, we are slowly folding + // normalization into this trait and will come back to remove this in the near + // future. + + // code from NormalizingClosureTyper: + // the substitutions in `substs` are already monomorphized, + // but we still must normalize associated types + // normalize_associated_type(self.param_env.tcx, &closure_ty) + normalize_associated_type(&self.tcx, &closure_ty) + // panic!("see issue 26597: fufillment context refactor must occur") + } else { + closure_ty + } + } + + pub fn closure_upvars(&self, + def_id: ast::DefId, + substs: &Substs<'tcx>) + -> Option>> + { + let result = ty::ctxt::closure_upvars(self, def_id, substs); + + if self.normalize { + // NOTE: this flag is currently *always* set to false, we are slowly folding + // normalization into this trait and will come back to remove this in the near + // future. + + // code from NormalizingClosureTyper: + // the substitutions in `substs` are already monomorphized, + // but we still must normalize associated types + // monomorphize::normalize_associated_type(self.param_env.tcx, &result) + // panic!("see issue 26597: fufillment context refactor must occur") + normalize_associated_type(&self.tcx, &result) + } else { + result + } + } } impl<'tcx> TypeTrace<'tcx> { diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 7d237a511c4..68001ae1564 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -110,11 +110,9 @@ use self::LiveNodeKind::*; use self::VarKind::*; use middle::def::*; -use middle::mem_categorization::Typer; use middle::pat_util; use middle::region; use middle::ty; -use middle::ty::ClosureTyper; use lint; use util::nodemap::NodeMap; diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 867174ffbc5..32fbd773900 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -77,14 +77,12 @@ use middle::infer; use middle::check_const; use middle::def; use middle::region; -use middle::ty::{self, Ty, ClosureTyper}; -use util::nodemap::NodeMap; +use middle::ty::{self, Ty}; use syntax::ast::{MutImmutable, MutMutable}; use syntax::ast; use syntax::codemap::Span; -use std::cell::Ref; use std::fmt; use std::rc::Rc; @@ -264,35 +262,6 @@ pub struct MemCategorizationContext<'t, 'a: 't, 'tcx : 'a> { pub type McResult = Result; -/// The `Typer` trait provides the interface for the mem-categorization -/// module to the results of the type check. It can be used to query -/// the type assigned to an expression node, to inquire after adjustments, -/// and so on. -/// -/// This interface is needed because mem-categorization is used from -/// two places: `regionck` and `borrowck`. `regionck` executes before -/// type inference is complete, and hence derives types and so on from -/// intermediate tables. This also implies that type errors can occur, -/// and hence `node_ty()` and friends return a `Result` type -- any -/// error will propagate back up through the mem-categorization -/// routines. -/// -/// In the borrow checker, in contrast, type checking is complete and we -/// know that no errors have occurred, so we simply consult the tcx and we -/// can be sure that only `Ok` results will occur. -pub trait Typer<'tcx> : ty::ClosureTyper<'tcx> { - fn node_ty(&self, id: ast::NodeId) -> McResult>; - fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult>; - fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool; - fn node_method_ty(&self, method_call: ty::MethodCall) -> Option>; - fn node_method_origin(&self, method_call: ty::MethodCall) - -> Option>; - fn adjustments(&self) -> Ref>>; - fn is_method_call(&self, id: ast::NodeId) -> bool; - fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option; - fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option; -} - impl MutabilityCategory { pub fn from_mutbl(m: ast::Mutability) -> MutabilityCategory { let ret = match m { diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs index 25b336f0c7a..977d0577e48 100644 --- a/src/librustc/middle/traits/coherence.rs +++ b/src/librustc/middle/traits/coherence.rs @@ -38,7 +38,7 @@ pub fn overlapping_impls(infcx: &InferCtxt, impl1_def_id, impl2_def_id); - let selcx = &mut SelectionContext::intercrate(infcx, infcx); + let selcx = &mut SelectionContext::intercrate(infcx); infcx.probe(|_| { overlap(selcx, impl1_def_id, impl2_def_id) || overlap(selcx, impl2_def_id, impl1_def_id) }) diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs index a769ef8233e..08cb3e57015 100644 --- a/src/librustc/middle/traits/fulfill.rs +++ b/src/librustc/middle/traits/fulfill.rs @@ -132,7 +132,6 @@ impl<'tcx> FulfillmentContext<'tcx> { /// `projection_ty` again. pub fn normalize_projection_type<'a>(&mut self, infcx: &InferCtxt<'a,'tcx>, - typer: &ty::ClosureTyper<'tcx>, projection_ty: ty::ProjectionTy<'tcx>, cause: ObligationCause<'tcx>) -> Ty<'tcx> @@ -144,7 +143,7 @@ impl<'tcx> FulfillmentContext<'tcx> { // FIXME(#20304) -- cache - let mut selcx = SelectionContext::new(infcx, typer); + let mut selcx = SelectionContext::new(infcx); let normalized = project::normalize_projection_type(&mut selcx, projection_ty, cause, 0); for obligation in normalized.obligations { @@ -208,11 +207,10 @@ impl<'tcx> FulfillmentContext<'tcx> { } pub fn select_all_or_error<'a>(&mut self, - infcx: &InferCtxt<'a,'tcx>, - typer: &ty::ClosureTyper<'tcx>) + infcx: &InferCtxt<'a,'tcx>) -> Result<(),Vec>> { - try!(self.select_where_possible(infcx, typer)); + try!(self.select_where_possible(infcx)); // Anything left is ambiguous. let errors: Vec = @@ -233,20 +231,18 @@ impl<'tcx> FulfillmentContext<'tcx> { /// gaining type information. It'd be equally valid to use `select_where_possible` but it /// results in `O(n^2)` performance (#18208). pub fn select_new_obligations<'a>(&mut self, - infcx: &InferCtxt<'a,'tcx>, - typer: &ty::ClosureTyper<'tcx>) + infcx: &InferCtxt<'a,'tcx>) -> Result<(),Vec>> { - let mut selcx = SelectionContext::new(infcx, typer); + let mut selcx = SelectionContext::new(infcx); self.select(&mut selcx, true) } pub fn select_where_possible<'a>(&mut self, - infcx: &InferCtxt<'a,'tcx>, - typer: &ty::ClosureTyper<'tcx>) + infcx: &InferCtxt<'a,'tcx>) -> Result<(),Vec>> { - let mut selcx = SelectionContext::new(infcx, typer); + let mut selcx = SelectionContext::new(infcx); self.select(&mut selcx, false) } diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index 8c065e182cd..a39fe453664 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -312,7 +312,6 @@ pub fn predicates_for_generics<'tcx>(cause: ObligationCause<'tcx>, /// conservative towards *no impl*, which is the opposite of the /// `evaluate` methods). pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, - typer: &ty::ClosureTyper<'tcx>, ty: Ty<'tcx>, bound: ty::BuiltinBound, span: Span) @@ -334,7 +333,7 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, // Note: we only assume something is `Copy` if we can // *definitively* show that it implements `Copy`. Otherwise, // assume it is move; linear is always ok. - match fulfill_cx.select_all_or_error(infcx, typer) { + match fulfill_cx.select_all_or_error(infcx) { Ok(()) => { debug!("type_known_to_meet_builtin_bound: ty={:?} bound={:?} success", ty, @@ -398,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), false); - let predicates = match fully_normalize(&infcx, &infcx, cause, + let predicates = match fully_normalize(&infcx, cause, &infcx.parameter_environment.caller_bounds) { Ok(predicates) => predicates, Err(errors) => { @@ -429,7 +428,6 @@ pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvi } pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, - closure_typer: &ty::ClosureTyper<'tcx>, cause: ObligationCause<'tcx>, value: &T) -> Result>> @@ -437,7 +435,7 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, { debug!("normalize_param_env(value={:?})", value); - let mut selcx = &mut SelectionContext::new(infcx, closure_typer); + let mut selcx = &mut SelectionContext::new(infcx); // FIXME (@jroesch): I'm not sure if this is a bug or not, needs // further investigation. It appears that by reusing the fulfillment_cx // here we incur more obligations and later trip an asssertion on @@ -458,7 +456,7 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, for obligation in obligations { fulfill_cx.register_predicate_obligation(selcx.infcx(), obligation); } - try!(fulfill_cx.select_all_or_error(infcx, closure_typer)); + try!(fulfill_cx.select_all_or_error(infcx)); let resolved_value = infcx.resolve_type_vars_if_possible(&normalized_value); debug!("normalize_param_env: resolved_value={:?}", resolved_value); Ok(resolved_value) diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index ae15c8aa8e0..3bc4fd0c0a1 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -55,8 +55,6 @@ use util::nodemap::FnvHashMap; pub struct SelectionContext<'cx, 'tcx:'cx> { infcx: &'cx InferCtxt<'cx, 'tcx>, - closure_typer: &'cx (ty::ClosureTyper<'tcx>+'cx), - /// Freshener used specifically for skolemizing entries on the /// obligation stack. This ensures that all entries on the stack /// at one time will have the same set of skolemized entries, @@ -244,23 +242,19 @@ enum EvaluationResult<'tcx> { } impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { - pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>, - closure_typer: &'cx ty::ClosureTyper<'tcx>) + pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>) -> SelectionContext<'cx, 'tcx> { SelectionContext { infcx: infcx, - closure_typer: closure_typer, freshener: infcx.freshener(), intercrate: false, } } - pub fn intercrate(infcx: &'cx InferCtxt<'cx, 'tcx>, - closure_typer: &'cx ty::ClosureTyper<'tcx>) + pub fn intercrate(infcx: &'cx InferCtxt<'cx, 'tcx>) -> SelectionContext<'cx, 'tcx> { SelectionContext { infcx: infcx, - closure_typer: closure_typer, freshener: infcx.freshener(), intercrate: true, } @@ -275,11 +269,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } pub fn param_env(&self) -> &'cx ty::ParameterEnvironment<'cx, 'tcx> { - self.closure_typer.param_env() + self.infcx.param_env() } - pub fn closure_typer(&self) -> &'cx (ty::ClosureTyper<'tcx>+'cx) { - self.closure_typer + pub fn closure_typer(&self) -> &'cx InferCtxt<'cx, 'tcx> { + self.infcx } /////////////////////////////////////////////////////////////////////////// @@ -1163,7 +1157,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { kind, obligation); - match self.closure_typer.closure_kind(closure_def_id) { + match self.infcx.closure_kind(closure_def_id) { Some(closure_kind) => { debug!("assemble_unboxed_candidates: closure_kind = {:?}", closure_kind); if closure_kind.extends(kind) { @@ -1727,7 +1721,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return ok_if(Vec::new()); } - match self.closure_typer.closure_upvars(def_id, substs) { + match self.infcx.closure_upvars(def_id, substs) { Some(upvars) => ok_if(upvars.iter().map(|c| c.ty).collect()), None => { debug!("assemble_builtin_bound_candidates: no upvar types available yet"); @@ -1865,7 +1859,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::TyClosure(def_id, substs) => { assert_eq!(def_id.krate, ast::LOCAL_CRATE); - match self.closure_typer.closure_upvars(def_id, substs) { + match self.infcx.closure_upvars(def_id, substs) { Some(upvars) => { Some(upvars.iter().map(|c| c.ty).collect()) } @@ -2844,7 +2838,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { substs: &Substs<'tcx>) -> ty::PolyTraitRef<'tcx> { - let closure_type = self.closure_typer.closure_type(closure_def_id, substs); + let closure_type = self.infcx.closure_type(closure_def_id, substs); let ty::Binder((trait_ref, _)) = util::closure_trait_ref_and_return_type(self.tcx(), obligation.predicate.def_id(), diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 23aa840703b..e20df807c87 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -52,7 +52,6 @@ use middle::dependency_format; use middle::fast_reject; use middle::free_region::FreeRegionMap; use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; -use middle::mem_categorization::Typer; use middle::region; use middle::resolve_lifetime; use middle::infer; @@ -3179,35 +3178,6 @@ impl ClosureKind { } } -pub trait ClosureTyper<'tcx> { - fn tcx(&self) -> &ctxt<'tcx> { - self.param_env().tcx - } - - fn param_env<'a>(&'a self) -> &'a ty::ParameterEnvironment<'a, 'tcx>; - - /// Is this a `Fn`, `FnMut` or `FnOnce` closure? During typeck, - /// returns `None` if the kind of this closure has not yet been - /// inferred. - fn closure_kind(&self, - def_id: ast::DefId) - -> Option; - - /// Returns the argument/return types of this closure. - fn closure_type(&self, - def_id: ast::DefId, - substs: &subst::Substs<'tcx>) - -> ty::ClosureTy<'tcx>; - - /// Returns the set of all upvars and their transformed - /// types. During typeck, maybe return `None` if the upvar types - /// have not yet been inferred. - fn closure_upvars(&self, - def_id: ast::DefId, - substs: &Substs<'tcx>) - -> Option>>; -} - impl<'tcx> CommonTypes<'tcx> { fn new(arena: &'tcx TypedArena>, interner: &mut FnvHashMap, Ty<'tcx>>) @@ -4406,7 +4376,7 @@ impl<'tcx> TyS<'tcx> { let tcx = param_env.tcx; let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(param_env.clone()), false); - let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, &infcx, + let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, self, bound, span); debug!("Ty::impls_bound({:?}, {:?}) = {:?}", @@ -6116,7 +6086,7 @@ impl<'tcx> ctxt<'tcx> { } // Returns a list of `ClosureUpvar`s for each upvar. - pub fn closure_upvars(typer: &Typer<'tcx>, + pub fn closure_upvars<'a>(typer: &infer::InferCtxt<'a, 'tcx>, closure_id: ast::DefId, substs: &Substs<'tcx>) -> Option>> @@ -6127,7 +6097,7 @@ impl<'tcx> ctxt<'tcx> { // This may change if abstract return types of some sort are // implemented. assert!(closure_id.krate == ast::LOCAL_CRATE); - let tcx = typer.tcx(); + let tcx = typer.tcx; match tcx.freevars.borrow().get(&closure_id.node) { None => Some(vec![]), Some(ref freevars) => { diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 3cf2a62b3b6..3a4318527fb 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -30,7 +30,6 @@ use rustc::middle::dataflow::KillFrom; use rustc::middle::expr_use_visitor as euv; use rustc::middle::free_region::FreeRegionMap; use rustc::middle::mem_categorization as mc; -use rustc::middle::mem_categorization::Typer; use rustc::middle::region; use rustc::middle::ty::{self, Ty}; diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 5661109ab45..2e812a0a780 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -30,7 +30,6 @@ use metadata::{csearch, decoder}; use middle::def::*; -use middle::mem_categorization::Typer; use middle::subst::Substs; use middle::ty::{self, Ty}; use middle::{def, pat_util, stability}; diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs index b96dcf940a8..eca9891c57c 100644 --- a/src/librustc_trans/trans/adt.rs +++ b/src/librustc_trans/trans/adt.rs @@ -51,7 +51,7 @@ use llvm::{ValueRef, True, IntEQ, IntNE}; use back::abi::FAT_PTR_ADDR; use middle::subst; use middle::infer; -use middle::ty::{self, Ty, ClosureTyper}; +use middle::ty::{self, Ty}; use middle::ty::Disr; use syntax::ast; use syntax::attr; diff --git a/src/librustc_trans/trans/attributes.rs b/src/librustc_trans/trans/attributes.rs index fd704ed2d37..25cde149df1 100644 --- a/src/librustc_trans/trans/attributes.rs +++ b/src/librustc_trans/trans/attributes.rs @@ -11,7 +11,7 @@ use libc::{c_uint, c_ulonglong}; use llvm::{self, ValueRef, AttrHelper}; -use middle::ty::{self, ClosureTyper}; +use middle::ty; use middle::infer; use session::config::NoDebugInfo; use syntax::abi; diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 088df7288be..156d591b909 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -41,7 +41,7 @@ use middle::infer; use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem}; use middle::weak_lang_items; use middle::subst::Substs; -use middle::ty::{self, Ty, ClosureTyper, HasTypeFlags}; +use middle::ty::{self, Ty, HasTypeFlags}; use rustc::ast_map; use session::config::{self, NoDebugInfo}; use session::Session; diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index c9bab6861ca..5fd0f92400f 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -11,7 +11,6 @@ use arena::TypedArena; use back::link::{self, mangle_internal_name_by_path_and_seq}; use llvm::{ValueRef, get_params}; -use middle::mem_categorization::Typer; use middle::infer; use trans::adt; use trans::attributes; @@ -26,7 +25,7 @@ use trans::declare; use trans::expr; use trans::monomorphize::{self, MonoId}; use trans::type_of::*; -use middle::ty::{self, ClosureTyper}; +use middle::ty; use middle::subst::Substs; use session::config::FullDebugInfo; diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 598029b842b..6dffb3fe2a7 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -22,8 +22,6 @@ use middle::cfg; use middle::def; use middle::infer; use middle::lang_items::LangItem; -use middle::mem_categorization::Typer; -use middle::ty::ClosureTyper; use middle::region; use middle::subst::{self, Substs}; use trans::base; @@ -872,7 +870,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // Do the initial selection for the obligation. This yields the // shallow result we are looking for -- that is, what specific impl. let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables); - let mut selcx = traits::SelectionContext::new(&infcx, &infcx); + let mut selcx = traits::SelectionContext::new(&infcx); let obligation = traits::Obligation::new(traits::ObligationCause::misc(span, ast::DUMMY_NODE_ID), @@ -931,7 +929,7 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let tcx = ccx.tcx(); let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, true); - let mut selcx = traits::SelectionContext::new(&infcx, &infcx); + let mut selcx = traits::SelectionContext::new(&infcx); let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); let cause = traits::ObligationCause::dummy(); let traits::Normalized { value: predicates, obligations } = @@ -979,12 +977,11 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &infer::InferCtxt<'a,'tcx>, { debug!("drain_fulfillment_cx(result={:?})", result); - // this is stupid but temporary - let typer: &ClosureTyper<'tcx> = infcx; + // In principle, we only need to do this so long as `result` // contains unbound type parameters. It could be a slight // optimization to stop iterating early. - match fulfill_cx.select_all_or_error(infcx, typer) { + match fulfill_cx.select_all_or_error(infcx) { Ok(()) => { } Err(errors) => { return Err(errors); diff --git a/src/librustc_trans/trans/debuginfo/gdb.rs b/src/librustc_trans/trans/debuginfo/gdb.rs index a6f1199d0ff..f7b0f37c9ff 100644 --- a/src/librustc_trans/trans/debuginfo/gdb.rs +++ b/src/librustc_trans/trans/debuginfo/gdb.rs @@ -16,7 +16,6 @@ use llvm::ValueRef; use trans::common::{C_bytes, CrateContext}; use trans::declare; use trans::type_::Type; -use middle::ty::ClosureTyper; use session::config::NoDebugInfo; use std::ffi::CString; diff --git a/src/librustc_trans/trans/debuginfo/metadata.rs b/src/librustc_trans/trans/debuginfo/metadata.rs index 12892c87b46..45349969a0b 100644 --- a/src/librustc_trans/trans/debuginfo/metadata.rs +++ b/src/librustc_trans/trans/debuginfo/metadata.rs @@ -32,7 +32,7 @@ use trans::{type_of, adt, machine, monomorphize}; use trans::common::{self, CrateContext, FunctionContext, Block}; use trans::_match::{BindingInfo, TrByCopy, TrByMove, TrByRef}; use trans::type_::Type; -use middle::ty::{self, Ty, ClosureTyper}; +use middle::ty::{self, Ty}; use session::config::{self, FullDebugInfo}; use util::nodemap::FnvHashMap; use util::common::path2cstr; diff --git a/src/librustc_trans/trans/debuginfo/mod.rs b/src/librustc_trans/trans/debuginfo/mod.rs index 7487e8d331b..ebe5e832e6f 100644 --- a/src/librustc_trans/trans/debuginfo/mod.rs +++ b/src/librustc_trans/trans/debuginfo/mod.rs @@ -30,7 +30,7 @@ use rustc::ast_map; use trans::common::{NodeIdAndSpan, CrateContext, FunctionContext, Block}; use trans; use trans::monomorphize; -use middle::ty::{Ty, ClosureTyper}; +use middle::ty::Ty; use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo}; use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet}; diff --git a/src/librustc_trans/trans/debuginfo/namespace.rs b/src/librustc_trans/trans/debuginfo/namespace.rs index 2e5943a248a..8b33acdee8e 100644 --- a/src/librustc_trans/trans/debuginfo/namespace.rs +++ b/src/librustc_trans/trans/debuginfo/namespace.rs @@ -16,7 +16,6 @@ use llvm; use llvm::debuginfo::DIScope; use rustc::ast_map; use trans::common::CrateContext; -use middle::ty::ClosureTyper; use std::ffi::CString; use std::ptr; diff --git a/src/librustc_trans/trans/debuginfo/type_names.rs b/src/librustc_trans/trans/debuginfo/type_names.rs index 6ea43d7392c..f4116883199 100644 --- a/src/librustc_trans/trans/debuginfo/type_names.rs +++ b/src/librustc_trans/trans/debuginfo/type_names.rs @@ -14,7 +14,7 @@ use super::namespace::crate_root_namespace; use trans::common::CrateContext; use middle::subst::{self, Substs}; -use middle::ty::{self, Ty, ClosureTyper}; +use middle::ty::{self, Ty}; use syntax::ast; use syntax::parse::token; @@ -225,4 +225,3 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, output.push('>'); } } - diff --git a/src/librustc_trans/trans/declare.rs b/src/librustc_trans/trans/declare.rs index 0eaaaaa5b34..b29da9d560f 100644 --- a/src/librustc_trans/trans/declare.rs +++ b/src/librustc_trans/trans/declare.rs @@ -20,7 +20,7 @@ //! * Use define_* family of methods when you might be defining the ValueRef. //! * When in doubt, define. use llvm::{self, ValueRef}; -use middle::ty::{self, ClosureTyper}; +use middle::ty; use middle::infer; use syntax::abi; use trans::attributes; diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 045cc69bf95..39bb9b25be7 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -56,7 +56,6 @@ use llvm::{self, ValueRef, TypeKind}; use middle::check_const; use middle::def; use middle::lang_items::CoerceUnsizedTraitLangItem; -use middle::mem_categorization::Typer; use middle::subst::{Substs, VecPerParamSpace}; use middle::traits; use trans::{_match, adt, asm, base, callee, closure, consts, controlflow}; diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index e46c3b5fab1..1b01fb6c7f8 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -17,7 +17,6 @@ use middle::subst::{Subst, Substs}; use middle::subst::VecPerParamSpace; use middle::subst; use middle::traits; -use middle::ty::ClosureTyper; use rustc::ast_map; use trans::base::*; use trans::build::*; diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index b297a731d29..3ef72e2c4af 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -322,10 +322,8 @@ 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::normalizing_infer_ctxt(tcx, &tcx.tables); - let mut selcx = traits::SelectionContext::new(&infcx, &infcx); + let mut selcx = traits::SelectionContext::new(&infcx); let cause = traits::ObligationCause::dummy(); let traits::Normalized { value: result, obligations } = traits::normalize(&mut selcx, cause, &value); diff --git a/src/librustc_typeck/check/assoc.rs b/src/librustc_typeck/check/assoc.rs index 4eafbaaf794..75263c35d59 100644 --- a/src/librustc_typeck/check/assoc.rs +++ b/src/librustc_typeck/check/assoc.rs @@ -11,13 +11,13 @@ use middle::infer::InferCtxt; use middle::traits::{self, FulfillmentContext, Normalized, MiscObligation, SelectionContext, ObligationCause}; -use middle::ty::{self, HasTypeFlags}; +use middle::ty::HasTypeFlags; use middle::ty_fold::TypeFoldable; use syntax::ast; use syntax::codemap::Span; +//FIME(@jroesch): Refactor this pub fn normalize_associated_types_in<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, - typer: &(ty::ClosureTyper<'tcx>+'a), fulfillment_cx: &mut FulfillmentContext<'tcx>, span: Span, body_id: ast::NodeId, @@ -26,7 +26,7 @@ pub fn normalize_associated_types_in<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, where T : TypeFoldable<'tcx> + HasTypeFlags { debug!("normalize_associated_types_in(value={:?})", value); - let mut selcx = SelectionContext::new(infcx, typer); + let mut selcx = SelectionContext::new(infcx); let cause = ObligationCause::new(span, body_id, MiscObligation); let Normalized { value: result, obligations } = traits::normalize(&mut selcx, cause, value); debug!("normalize_associated_types_in: result={:?} predicates={:?}", diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index d29c0494572..f32a4fe43d6 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -27,7 +27,7 @@ use super::write_call; use CrateCtxt; use middle::infer; -use middle::ty::{self, Ty, ClosureTyper}; +use middle::ty::{self, Ty}; use syntax::ast; use syntax::codemap::Span; use syntax::parse::token; diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index b38b6884a98..a0abef74907 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -273,7 +273,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { }; let source = source.adjust_for_autoref(self.tcx(), reborrow); - let mut selcx = traits::SelectionContext::new(self.fcx.infcx(), self.fcx.infcx()); + let mut selcx = traits::SelectionContext::new(self.fcx.infcx()); // Use a FIFO queue for this custom fulfillment procedure. let mut queue = VecDeque::new(); diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index c05b95f4aeb..7926394ebb5 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -246,7 +246,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, debug!("compare_impl_method: trait_bounds={:?}", infcx.parameter_environment.caller_bounds); - let mut selcx = traits::SelectionContext::new(&infcx, &infcx); + let mut selcx = traits::SelectionContext::new(&infcx); for predicate in impl_pred.fns { let traits::Normalized { value: predicate, .. } = @@ -293,7 +293,6 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, impl_sig.subst(tcx, impl_to_skol_substs); let impl_sig = assoc::normalize_associated_types_in(&infcx, - &infcx, &mut fulfillment_cx, impl_m_span, impl_m_body_id, @@ -312,7 +311,6 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, trait_sig.subst(tcx, &trait_to_skol_substs); let trait_sig = assoc::normalize_associated_types_in(&infcx, - &infcx, &mut fulfillment_cx, impl_m_span, impl_m_body_id, @@ -347,7 +345,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, // Check that all obligations are satisfied by the implementation's // version. - match fulfillment_cx.select_all_or_error(&infcx, &infcx) { + match fulfillment_cx.select_all_or_error(&infcx) { Err(ref errors) => { traits::report_fulfillment_errors(&infcx, errors) } Ok(_) => {} } @@ -456,21 +454,21 @@ pub fn compare_const_impl<'tcx>(tcx: &ty::ctxt<'tcx>, // There is no "body" here, so just pass dummy id. let impl_ty = assoc::normalize_associated_types_in(&infcx, - &infcx, &mut fulfillment_cx, impl_c_span, 0, &impl_ty); + debug!("compare_const_impl: impl_ty={:?}", impl_ty); let trait_ty = assoc::normalize_associated_types_in(&infcx, - &infcx, &mut fulfillment_cx, impl_c_span, 0, &trait_ty); + debug!("compare_const_impl: trait_ty={:?}", trait_ty); diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 9c2d1c4a34d..7a887fac9d4 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -12,7 +12,6 @@ use super::probe; use check::{self, FnCtxt, NoPreference, PreferMutLvalue, callee, demand}; use check::UnresolvedTypeAction; -use middle::mem_categorization::Typer; use middle::subst::{self}; use middle::traits; use middle::ty::{self, Ty}; diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index f312db9c4dc..7ed5c69ad61 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -195,7 +195,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, poly_trait_ref.to_predicate()); // Now we want to know if this can be matched - let mut selcx = traits::SelectionContext::new(fcx.infcx(), fcx.infcx()); + let mut selcx = traits::SelectionContext::new(fcx.infcx()); if !selcx.evaluate_obligation(&obligation) { debug!("--> Cannot match obligation"); return None; // Cannot be matched, no such method resolution is possible. diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 94a2050829d..8eb4716cb2a 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -421,7 +421,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { // We can't use normalize_associated_types_in as it will pollute the // fcx's fulfillment context after this probe is over. let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id); - let mut selcx = &mut traits::SelectionContext::new(self.fcx.infcx(), self.fcx.infcx()); + let mut selcx = &mut traits::SelectionContext::new(self.fcx.infcx()); let traits::Normalized { value: xform_self_ty, obligations } = traits::normalize(selcx, cause, &xform_self_ty); debug!("assemble_inherent_impl_probe: xform_self_ty = {:?}", @@ -681,7 +681,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { // as it will pollute the fcx's fulfillment context after this probe // is over. let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id); - let mut selcx = &mut traits::SelectionContext::new(self.fcx.infcx(), self.fcx.infcx()); + let mut selcx = &mut traits::SelectionContext::new(self.fcx.infcx()); let traits::Normalized { value: xform_self_ty, obligations } = traits::normalize(selcx, cause, &xform_self_ty); @@ -1076,7 +1076,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { match probe.kind { InherentImplCandidate(impl_def_id, ref substs, ref ref_obligations) | ExtensionImplCandidate(impl_def_id, _, ref substs, _, ref ref_obligations) => { - let selcx = &mut traits::SelectionContext::new(self.infcx(), self.fcx.infcx()); + let selcx = &mut traits::SelectionContext::new(self.infcx()); let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id); // Check whether the impl imposes obligations we have to worry about. diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index b81b672e684..d6a8b3583f8 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -102,7 +102,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, let obligation = Obligation::misc(span, fcx.body_id, poly_trait_ref.to_predicate()); - let mut selcx = SelectionContext::new(infcx, fcx.infcx()); + let mut selcx = SelectionContext::new(infcx); if selcx.evaluate_obligation(&obligation) { span_stored_function(); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 4d750f88093..477b6e98256 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -305,7 +305,6 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> { } fn normalize_associated_types_in(&self, - typer: &ty::ClosureTyper<'tcx>, span: Span, body_id: ast::NodeId, value: &T) @@ -314,7 +313,6 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> { { let mut fulfillment_cx = self.infcx.fulfillment_cx.borrow_mut(); assoc::normalize_associated_types_in(&self.infcx, - typer, &mut fulfillment_cx, span, body_id, @@ -431,8 +429,7 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, ccx.tcx.liberate_late_bound_regions(region::DestructionScopeData::new(body.id), &fn_sig); let fn_sig = - inh.normalize_associated_types_in(&inh.infcx, - body.span, + inh.normalize_associated_types_in(body.span, body.id, &fn_sig); @@ -1377,7 +1374,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn normalize_associated_types_in(&self, span: Span, value: &T) -> T where T : TypeFoldable<'tcx> + HasTypeFlags { - self.inh.normalize_associated_types_in(self.infcx(), span, self.body_id, value) + self.inh.normalize_associated_types_in(span, self.body_id, value) } fn normalize_associated_type(&self, @@ -1394,7 +1391,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .fulfillment_cx .borrow_mut() .normalize_projection_type(self.infcx(), - self.infcx(), ty::ProjectionTy { trait_ref: trait_ref, item_name: item_name, @@ -1504,7 +1500,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { -> bool { traits::type_known_to_meet_builtin_bound(self.infcx(), - self.infcx(), ty, ty::BoundSized, span) @@ -1750,7 +1745,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.select_all_obligations_and_apply_defaults(); let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut(); - match fulfillment_cx.select_all_or_error(self.infcx(), self.infcx()) { + match fulfillment_cx.select_all_or_error(self.infcx()) { Ok(()) => { } Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); } } @@ -1761,7 +1756,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match self.inh.infcx.fulfillment_cx .borrow_mut() - .select_where_possible(self.infcx(), self.infcx()) + .select_where_possible(self.infcx()) { Ok(()) => { } Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); } @@ -1776,7 +1771,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match self.inh.infcx.fulfillment_cx .borrow_mut() - .select_new_obligations(self.infcx(), self.infcx()) + .select_new_obligations(self.infcx()) { Ok(()) => { } Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); } diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index a98bcc247ed..bb3c9f9fb54 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -86,13 +86,12 @@ use astconv::AstConv; use check::dropck; use check::FnCtxt; use middle::free_region::FreeRegionMap; -use middle::infer::InferCtxt; use middle::implicator; use middle::mem_categorization as mc; use middle::region::CodeExtent; use middle::subst::Substs; use middle::traits; -use middle::ty::{self, ClosureTyper, ReScope, Ty, MethodCall, HasTypeFlags}; +use middle::ty::{self, ReScope, Ty, MethodCall, HasTypeFlags}; use middle::infer::{self, GenericKind}; use middle::pat_util; @@ -360,7 +359,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> { debug!("relate_free_regions(t={:?})", ty); let body_scope = CodeExtent::from_node_id(body_id); let body_scope = ty::ReScope(body_scope); - let implications = implicator::implications(self.fcx.infcx(), self.fcx.infcx(), body_id, + let implications = implicator::implications(self.fcx.infcx(), body_id, ty, body_scope, span); // Record any relations between free regions that we observe into the free-region-map. @@ -1409,7 +1408,7 @@ pub fn type_must_outlive<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>, ty, region); - let implications = implicator::implications(rcx.fcx.infcx(), rcx.fcx.infcx(), rcx.body_id, + let implications = implicator::implications(rcx.fcx.infcx(), rcx.body_id, ty, region, origin.span()); for implication in implications { debug!("implication: {:?}", implication); diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index df01b99fd9b..7cf7d73a566 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -268,7 +268,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { let predicates = fcx.tcx().lookup_super_predicates(poly_trait_ref.def_id()); let predicates = predicates.instantiate_supertrait(fcx.tcx(), &poly_trait_ref); let predicates = { - let selcx = &mut traits::SelectionContext::new(fcx.infcx(), fcx.infcx()); + let selcx = &mut traits::SelectionContext::new(fcx.infcx()); traits::normalize(selcx, cause.clone(), &predicates) }; for predicate in predicates.value.predicates { diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 0650f7deb06..fca23a1b029 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -540,8 +540,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { fulfill_cx.register_predicate_obligation(&infcx, predicate); // Check that all transitive obligations are satisfied. - if let Err(errors) = fulfill_cx.select_all_or_error(&infcx, - &infcx) { + if let Err(errors) = fulfill_cx.select_all_or_error(&infcx) { traits::report_fulfillment_errors(&infcx, &errors); } From 7a8f83a6e59abb53adaafe7a9f70ff7069feefae Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Tue, 30 Jun 2015 02:39:47 -0700 Subject: [PATCH 08/10] Clean up patch --- src/librustc/middle/infer/mod.rs | 18 ------------------ src/librustc/middle/mem_categorization.rs | 1 - src/librustc/middle/traits/mod.rs | 22 +++++++++++++--------- src/librustc_typeck/check/assoc.rs | 2 +- src/librustc_typeck/check/mod.rs | 3 --- src/librustc_typeck/coherence/mod.rs | 1 - 6 files changed, 14 insertions(+), 33 deletions(-) diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index a64fe8b9128..43be1beba91 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -1386,16 +1386,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .subst(self.tcx, substs); if self.normalize { - // NOTE: this flag is currently *always* set to false, we are slowly folding - // normalization into this trait and will come back to remove this in the near - // future. - - // code from NormalizingClosureTyper: - // the substitutions in `substs` are already monomorphized, - // but we still must normalize associated types - // normalize_associated_type(self.param_env.tcx, &closure_ty) normalize_associated_type(&self.tcx, &closure_ty) - // panic!("see issue 26597: fufillment context refactor must occur") } else { closure_ty } @@ -1409,15 +1400,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let result = ty::ctxt::closure_upvars(self, def_id, substs); if self.normalize { - // NOTE: this flag is currently *always* set to false, we are slowly folding - // normalization into this trait and will come back to remove this in the near - // future. - - // code from NormalizingClosureTyper: - // the substitutions in `substs` are already monomorphized, - // but we still must normalize associated types - // monomorphize::normalize_associated_type(self.param_env.tcx, &result) - // panic!("see issue 26597: fufillment context refactor must occur") normalize_associated_type(&self.tcx, &result) } else { result diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 32fbd773900..f506de525ff 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -257,7 +257,6 @@ impl ast_node for ast::Pat { #[derive(Copy, Clone)] pub struct MemCategorizationContext<'t, 'a: 't, 'tcx : 'a> { pub typer: &'t infer::InferCtxt<'a, 'tcx>, - // pub monomorphize: bool, } pub type McResult = Result; diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index a39fe453664..47002497acc 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -436,17 +436,20 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, debug!("normalize_param_env(value={:?})", value); let mut selcx = &mut SelectionContext::new(infcx); - // FIXME (@jroesch): I'm not sure if this is a bug or not, needs - // further investigation. It appears that by reusing the fulfillment_cx - // here we incur more obligations and later trip an asssertion on - // regionck.rs line 337. The two possibilities I see is that - // normalization is not actually fully happening and we - // have a bug else where or that we are adding a duplicate - // bound into the list causing its size to change. I think - // we should probably land this refactor and then come + // FIXME (@jroesch): + // I'm not sure if this is a bug or not, needs further investigation. + // It appears that by reusing the fulfillment_cx here we incur more + // obligations and later trip an asssertion on regionck.rs line 337. + // + // The two possibilities I see is: + // - normalization is not actually fully happening and we + // have a bug else where + // - we are adding a duplicate bound into the list causing + // its size to change. + // + // I think we should probably land this refactor and then come // back to this is a follow-up patch. let mut fulfill_cx = FulfillmentContext::new(false); - // let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); let Normalized { value: normalized_value, obligations } = project::normalize(selcx, cause, value); @@ -456,6 +459,7 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, for obligation in obligations { fulfill_cx.register_predicate_obligation(selcx.infcx(), obligation); } + try!(fulfill_cx.select_all_or_error(infcx)); let resolved_value = infcx.resolve_type_vars_if_possible(&normalized_value); debug!("normalize_param_env: resolved_value={:?}", resolved_value); diff --git a/src/librustc_typeck/check/assoc.rs b/src/librustc_typeck/check/assoc.rs index 75263c35d59..c80c48a9692 100644 --- a/src/librustc_typeck/check/assoc.rs +++ b/src/librustc_typeck/check/assoc.rs @@ -16,7 +16,7 @@ use middle::ty_fold::TypeFoldable; use syntax::ast; use syntax::codemap::Span; -//FIME(@jroesch): Refactor this +//FIXME(@jroesch): Ideally we should be able to drop the fulfillment_cx argument. pub fn normalize_associated_types_in<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, fulfillment_cx: &mut FulfillmentContext<'tcx>, span: Span, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 477b6e98256..b7ebf1abd2d 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -158,9 +158,6 @@ pub struct Inherited<'a, 'tcx: 'a> { // one is never copied into the tcx: it is only used by regionck. fn_sig_map: RefCell>>>, - // Tracks trait obligations incurred during this function body. - // fulfillment_cx: RefCell>, - // 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 // `FnOnce` closure. In that case, we defer full resolution of the diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index fca23a1b029..a1c5ad51dcd 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -631,7 +631,6 @@ fn subst_receiver_types_in_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>, pub fn check_coherence(crate_context: &CrateCtxt) { CoherenceChecker { crate_context: crate_context, - // XXXJAREDXXX: not sure if the bool is right here? inference_context: new_infer_ctxt(crate_context.tcx, &crate_context.tcx.tables, None, true), inherent_impls: RefCell::new(FnvHashMap()), }.check(crate_context.tcx.map.krate()); From ce089e50a4caa5ec583e79de32d94fb2934ca8df Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Wed, 1 Jul 2015 13:08:25 -0700 Subject: [PATCH 09/10] Address nits --- src/librustc/middle/check_match.rs | 11 +++++++++-- src/librustc/middle/check_rvalues.rs | 5 ++++- src/librustc/middle/infer/mod.rs | 2 ++ src/librustc/middle/traits/mod.rs | 4 ++-- src/librustc/middle/ty.rs | 2 +- src/librustc_trans/trans/common.rs | 1 - src/librustc_trans/trans/debuginfo/mod.rs | 2 +- 7 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 8e315901db2..a303c49bf8d 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -1113,7 +1113,10 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt, ast::PatIdent(ast::BindByValue(_), _, ref sub) => { let pat_ty = tcx.node_id_to_type(p.id); //FIXME: (@jroesch) this code should be floated up as well - let infcx = infer::new_infer_ctxt(cx.tcx, &cx.tcx.tables, Some(cx.param_env.clone()), false); + let infcx = infer::new_infer_ctxt(cx.tcx, + &cx.tcx.tables, + Some(cx.param_env.clone()), + false); if infcx.type_moves_by_default(pat_ty, pat.span) { check_move(p, sub.as_ref().map(|p| &**p)); } @@ -1143,7 +1146,11 @@ fn check_for_mutation_in_guard<'a, 'tcx>(cx: &'a MatchCheckCtxt<'a, 'tcx>, cx: cx, }; - let infcx = infer::new_infer_ctxt(cx.tcx, &cx.tcx.tables, Some(checker.cx.param_env.clone()), false); + let infcx = infer::new_infer_ctxt(cx.tcx, + &cx.tcx.tables, + Some(checker.cx.param_env.clone()), + false); + let mut visitor = ExprUseVisitor::new(&mut checker, &infcx); visitor.walk_expr(guard); } diff --git a/src/librustc/middle/check_rvalues.rs b/src/librustc/middle/check_rvalues.rs index 731e49192a8..c9017432473 100644 --- a/src/librustc/middle/check_rvalues.rs +++ b/src/librustc/middle/check_rvalues.rs @@ -41,7 +41,10 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for RvalueContext<'a, 'tcx> { { // FIXME (@jroesch) change this to be an inference context let param_env = ParameterEnvironment::for_item(self.tcx, fn_id); - let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, Some(param_env.clone()), false); + let infcx = infer::new_infer_ctxt(self.tcx, + &self.tcx.tables, + Some(param_env.clone()), + false); let mut delegate = RvalueContextDelegate { tcx: self.tcx, param_env: ¶m_env }; let mut euv = euv::ExprUseVisitor::new(&mut delegate, &infcx); euv.walk_fn(fd, b); diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 43be1beba91..7df37bdae07 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -1318,6 +1318,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool { let ty = self.resolve_type_vars_if_possible(&ty); !traits::type_known_to_meet_builtin_bound(self, ty, ty::BoundCopy, span) + // FIXME(@jroesch): should be able to use: + // ty.moves_by_default(&self.parameter_environment, span) } pub fn node_method_ty(&self, method_call: ty::MethodCall) diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index 47002497acc..5126a549887 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -436,7 +436,7 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, debug!("normalize_param_env(value={:?})", value); let mut selcx = &mut SelectionContext::new(infcx); - // FIXME (@jroesch): + // FIXME (@jroesch) ISSUE 26721 // I'm not sure if this is a bug or not, needs further investigation. // It appears that by reusing the fulfillment_cx here we incur more // obligations and later trip an asssertion on regionck.rs line 337. @@ -459,7 +459,7 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, for obligation in obligations { fulfill_cx.register_predicate_obligation(selcx.infcx(), obligation); } - + try!(fulfill_cx.select_all_or_error(infcx)); let resolved_value = infcx.resolve_type_vars_if_possible(&normalized_value); debug!("normalize_param_env: resolved_value={:?}", resolved_value); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index e20df807c87..b1b0097cbf6 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -4385,7 +4385,7 @@ impl<'tcx> TyS<'tcx> { is_impld } - // temp hack, probably should be private + // FIXME (@jroesch): I made this public to use it, not sure if should be private pub fn moves_by_default<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>, span: Span) -> bool { if self.flags.get().intersects(TypeFlags::MOVENESS_CACHED) { diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 6dffb3fe2a7..96564277cdc 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -22,7 +22,6 @@ use middle::cfg; use middle::def; use middle::infer; use middle::lang_items::LangItem; -use middle::region; use middle::subst::{self, Substs}; use trans::base; use trans::build; diff --git a/src/librustc_trans/trans/debuginfo/mod.rs b/src/librustc_trans/trans/debuginfo/mod.rs index ebe5e832e6f..3d1b384c2d9 100644 --- a/src/librustc_trans/trans/debuginfo/mod.rs +++ b/src/librustc_trans/trans/debuginfo/mod.rs @@ -30,7 +30,7 @@ use rustc::ast_map; use trans::common::{NodeIdAndSpan, CrateContext, FunctionContext, Block}; use trans; use trans::monomorphize; -use middle::ty::Ty; +use middle::ty::Ty; use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo}; use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet}; From c64bda322764792c272d65bb14e033974ea1f287 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Wed, 1 Jul 2015 19:29:17 -0700 Subject: [PATCH 10/10] Update librustc_driver/test.rs --- src/librustc_driver/test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index fb2f6b2b08d..128b0b7baab 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -140,7 +140,7 @@ fn test_env(source_string: &str, lang_items, stability::Index::new(krate), |tcx| { - let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false); body(Env { infcx: &infcx }); let free_regions = FreeRegionMap::new(); infcx.resolve_regions_and_report_errors(&free_regions, ast::CRATE_NODE_ID);