diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 04c29aaeb5a6..91fee77f0a7a 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 3ce76167e851..b96dcf940a89 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 b432560bc4b3..fd704ed2d378 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 0cd6bbad03aa..088df7288bec 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 b63780628554..c9bab6861ca0 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 92aeb9f7b720..1fc68790db07 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 1fbbf0763aa5..12892c87b468 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 646ca6733c3b..0eaaaaa5b341 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 b88251c69a0a..b297a731d29e 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); }