Remove NormalizingClosureTyper
This commit is contained in:
parent
0f13a3f361
commit
fb295a60b3
9 changed files with 204 additions and 94 deletions
|
@ -19,6 +19,7 @@ pub use self::TypeOrigin::*;
|
||||||
pub use self::ValuePairs::*;
|
pub use self::ValuePairs::*;
|
||||||
pub use self::fixup_err::*;
|
pub use self::fixup_err::*;
|
||||||
pub use middle::ty::IntVarValue;
|
pub use middle::ty::IntVarValue;
|
||||||
|
use middle::ty::ClosureTyper;
|
||||||
pub use self::freshen::TypeFreshener;
|
pub use self::freshen::TypeFreshener;
|
||||||
pub use self::region_inference::GenericKind;
|
pub use self::region_inference::GenericKind;
|
||||||
|
|
||||||
|
@ -29,7 +30,8 @@ use middle::region::CodeExtent;
|
||||||
use middle::subst;
|
use middle::subst;
|
||||||
use middle::subst::Substs;
|
use middle::subst::Substs;
|
||||||
use middle::subst::Subst;
|
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::{TyVid, IntVid, FloatVid, RegionVid, UnconstrainedNumeric};
|
||||||
use middle::ty::{self, Ty, HasTypeFlags};
|
use middle::ty::{self, Ty, HasTypeFlags};
|
||||||
use middle::ty_fold::{self, TypeFolder, TypeFoldable};
|
use middle::ty_fold::{self, TypeFolder, TypeFoldable};
|
||||||
|
@ -39,7 +41,7 @@ use std::cell::{RefCell, Ref};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::codemap;
|
use syntax::codemap;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::{Span, DUMMY_SP};
|
||||||
use util::nodemap::{FnvHashMap, NodeMap};
|
use util::nodemap::{FnvHashMap, NodeMap};
|
||||||
|
|
||||||
use self::combine::CombineFields;
|
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<ty::Tables<'tcx>>)
|
||||||
|
-> 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
|
/// Computes the least upper-bound of `a` and `b`. If this is not possible, reports an error and
|
||||||
/// returns ty::err.
|
/// returns ty::err.
|
||||||
pub fn common_supertype<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
|
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,
|
// the substitutions in `substs` are already monomorphized,
|
||||||
// but we still must normalize associated types
|
// but we still must normalize associated types
|
||||||
// normalize_associated_type(self.param_env.tcx, &closure_ty)
|
// 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 {
|
} else {
|
||||||
closure_ty
|
closure_ty
|
||||||
}
|
}
|
||||||
|
@ -579,13 +590,158 @@ impl<'a, 'tcx> ty::ClosureTyper<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
// the substitutions in `substs` are already monomorphized,
|
// the substitutions in `substs` are already monomorphized,
|
||||||
// but we still must normalize associated types
|
// but we still must normalize associated types
|
||||||
// monomorphize::normalize_associated_type(self.param_env.tcx, &result)
|
// 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 {
|
} else {
|
||||||
result
|
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<T,Vec<traits::FulfillmentError<'tcx>>>
|
||||||
|
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<T>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T>
|
||||||
|
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> {
|
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
pub fn freshen<T:TypeFoldable<'tcx>>(&self, t: T) -> T {
|
pub fn freshen<T:TypeFoldable<'tcx>>(&self, t: T) -> T {
|
||||||
t.fold_with(&mut self.freshener())
|
t.fold_with(&mut self.freshener())
|
||||||
|
|
|
@ -50,6 +50,7 @@ use std::rc::Rc;
|
||||||
use llvm::{ValueRef, True, IntEQ, IntNE};
|
use llvm::{ValueRef, True, IntEQ, IntNE};
|
||||||
use back::abi::FAT_PTR_ADDR;
|
use back::abi::FAT_PTR_ADDR;
|
||||||
use middle::subst;
|
use middle::subst;
|
||||||
|
use middle::infer;
|
||||||
use middle::ty::{self, Ty, ClosureTyper};
|
use middle::ty::{self, Ty, ClosureTyper};
|
||||||
use middle::ty::Disr;
|
use middle::ty::Disr;
|
||||||
use syntax::ast;
|
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))
|
Univariant(mk_struct(cx, &ftys[..], packed, t), dtor_to_init_u8(dtor))
|
||||||
}
|
}
|
||||||
ty::TyClosure(def_id, substs) => {
|
ty::TyClosure(def_id, substs) => {
|
||||||
let typer = NormalizingClosureTyper::new(cx.tcx());
|
let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables);
|
||||||
let upvars = typer.closure_upvars(def_id, substs).unwrap();
|
let upvars = infcx.closure_upvars(def_id, substs).unwrap();
|
||||||
let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();
|
let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();
|
||||||
Univariant(mk_struct(cx, &upvar_types[..], false, t), 0)
|
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
|
// Perhaps one of the upvars of this struct is non-zero
|
||||||
// Let's recurse and find out!
|
// Let's recurse and find out!
|
||||||
ty::TyClosure(def_id, substs) => {
|
ty::TyClosure(def_id, substs) => {
|
||||||
let typer = NormalizingClosureTyper::new(tcx);
|
let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables);
|
||||||
let upvars = typer.closure_upvars(def_id, substs).unwrap();
|
let upvars = infcx.closure_upvars(def_id, substs).unwrap();
|
||||||
let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();
|
let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();
|
||||||
|
|
||||||
for (j, &ty) in upvar_types.iter().enumerate() {
|
for (j, &ty) in upvar_types.iter().enumerate() {
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
use libc::{c_uint, c_ulonglong};
|
use libc::{c_uint, c_ulonglong};
|
||||||
use llvm::{self, ValueRef, AttrHelper};
|
use llvm::{self, ValueRef, AttrHelper};
|
||||||
use middle::ty::{self, ClosureTyper};
|
use middle::ty::{self, ClosureTyper};
|
||||||
|
use middle::infer;
|
||||||
use session::config::NoDebugInfo;
|
use session::config::NoDebugInfo;
|
||||||
use syntax::abi;
|
use syntax::abi;
|
||||||
use syntax::ast;
|
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 {
|
let (fn_sig, abi, env_ty) = match fn_type.sty {
|
||||||
ty::TyBareFn(_, ref f) => (&f.sig, f.abi, None),
|
ty::TyBareFn(_, ref f) => (&f.sig, f.abi, None),
|
||||||
ty::TyClosure(closure_did, substs) => {
|
ty::TyClosure(closure_did, substs) => {
|
||||||
let typer = common::NormalizingClosureTyper::new(ccx.tcx());
|
let infcx = infer::normalizing_infer_ctxt(ccx.tcx(), &ccx.tcx().tables);
|
||||||
function_type = typer.closure_type(closure_did, substs);
|
function_type = infcx.closure_type(closure_did, substs);
|
||||||
let self_type = base::self_type_for_closure(ccx, closure_did, fn_type);
|
let self_type = base::self_type_for_closure(ccx, closure_did, fn_type);
|
||||||
(&function_type.sig, abi::RustCall, Some(self_type))
|
(&function_type.sig, abi::RustCall, Some(self_type))
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ use llvm;
|
||||||
use metadata::{csearch, encoder, loader};
|
use metadata::{csearch, encoder, loader};
|
||||||
use middle::astencode;
|
use middle::astencode;
|
||||||
use middle::cfg;
|
use middle::cfg;
|
||||||
|
use middle::infer;
|
||||||
use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
|
use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
|
||||||
use middle::weak_lang_items;
|
use middle::weak_lang_items;
|
||||||
use middle::subst::Substs;
|
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) => {
|
ty::TyClosure(def_id, substs) => {
|
||||||
let repr = adt::represent_type(cx.ccx(), t);
|
let repr = adt::represent_type(cx.ccx(), t);
|
||||||
let typer = common::NormalizingClosureTyper::new(cx.tcx());
|
let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables);
|
||||||
let upvars = typer.closure_upvars(def_id, substs).unwrap();
|
let upvars = infcx.closure_upvars(def_id, substs).unwrap();
|
||||||
for (i, upvar) in upvars.iter().enumerate() {
|
for (i, upvar) in upvars.iter().enumerate() {
|
||||||
let llupvar = adt::trans_field_ptr(cx, &*repr, data_ptr, 0, i);
|
let llupvar = adt::trans_field_ptr(cx, &*repr, data_ptr, 0, i);
|
||||||
cx = f(cx, llupvar, upvar.ty);
|
cx = f(cx, llupvar, upvar.ty);
|
||||||
|
|
|
@ -12,6 +12,7 @@ use arena::TypedArena;
|
||||||
use back::link::{self, mangle_internal_name_by_path_and_seq};
|
use back::link::{self, mangle_internal_name_by_path_and_seq};
|
||||||
use llvm::{ValueRef, get_params};
|
use llvm::{ValueRef, get_params};
|
||||||
use middle::mem_categorization::Typer;
|
use middle::mem_categorization::Typer;
|
||||||
|
use middle::infer;
|
||||||
use trans::adt;
|
use trans::adt;
|
||||||
use trans::attributes;
|
use trans::attributes;
|
||||||
use trans::base::*;
|
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
|
// takes the same set of type arguments as the enclosing fn, and
|
||||||
// this function (`trans_closure`) is invoked at the point
|
// this function (`trans_closure`) is invoked at the point
|
||||||
// of the closure expression.
|
// 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<ty::Freevar> =
|
let freevars: Vec<ty::Freevar> =
|
||||||
tcx.with_freevars(id, |fv| fv.iter().cloned().collect());
|
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));
|
ccx.tn().val_to_string(llreffn));
|
||||||
|
|
||||||
let tcx = ccx.tcx();
|
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
|
// Find a version of the closure type. Substitute static for the
|
||||||
// region since it doesn't really matter.
|
// 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);
|
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.
|
// 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
|
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,
|
let llref_bare_fn_ty = tcx.mk_bare_fn(ty::BareFnTy { unsafety: unsafety,
|
||||||
abi: abi,
|
abi: abi,
|
||||||
|
|
|
@ -24,6 +24,7 @@ use middle::infer;
|
||||||
use middle::lang_items::LangItem;
|
use middle::lang_items::LangItem;
|
||||||
use middle::mem_categorization as mc;
|
use middle::mem_categorization as mc;
|
||||||
use middle::mem_categorization::Typer;
|
use middle::mem_categorization::Typer;
|
||||||
|
use middle::ty::ClosureTyper;
|
||||||
use middle::region;
|
use middle::region;
|
||||||
use middle::subst::{self, Substs};
|
use middle::subst::{self, Substs};
|
||||||
use trans::base;
|
use trans::base;
|
||||||
|
@ -642,8 +643,8 @@ impl<'blk, 'tcx> ty::ClosureTyper<'tcx> for BlockS<'blk, 'tcx> {
|
||||||
def_id: ast::DefId)
|
def_id: ast::DefId)
|
||||||
-> Option<ty::ClosureKind>
|
-> Option<ty::ClosureKind>
|
||||||
{
|
{
|
||||||
let typer = NormalizingClosureTyper::new(self.tcx());
|
let infcx = infer::normalizing_infer_ctxt(self.tcx(), &self.tcx().tables);
|
||||||
typer.closure_kind(def_id)
|
infcx.closure_kind(def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn closure_type(&self,
|
fn closure_type(&self,
|
||||||
|
@ -651,8 +652,8 @@ impl<'blk, 'tcx> ty::ClosureTyper<'tcx> for BlockS<'blk, 'tcx> {
|
||||||
substs: &subst::Substs<'tcx>)
|
substs: &subst::Substs<'tcx>)
|
||||||
-> ty::ClosureTy<'tcx>
|
-> ty::ClosureTy<'tcx>
|
||||||
{
|
{
|
||||||
let typer = NormalizingClosureTyper::new(self.tcx());
|
let infcx = infer::normalizing_infer_ctxt(self.tcx(), &self.tcx().tables);
|
||||||
typer.closure_type(def_id, substs)
|
infcx.closure_type(def_id, substs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn closure_upvars(&self,
|
fn closure_upvars(&self,
|
||||||
|
@ -660,8 +661,8 @@ impl<'blk, 'tcx> ty::ClosureTyper<'tcx> for BlockS<'blk, 'tcx> {
|
||||||
substs: &Substs<'tcx>)
|
substs: &Substs<'tcx>)
|
||||||
-> Option<Vec<ty::ClosureUpvar<'tcx>>>
|
-> Option<Vec<ty::ClosureUpvar<'tcx>>>
|
||||||
{
|
{
|
||||||
let typer = NormalizingClosureTyper::new(self.tcx());
|
let infcx = infer::new_infer_ctxt(self.tcx(), &self.tcx().tables, None, true);
|
||||||
typer.closure_upvars(def_id, substs)
|
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());
|
trait_ref, trait_ref.def_id());
|
||||||
|
|
||||||
tcx.populate_implementations_for_trait_if_necessary(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
|
// Do the initial selection for the obligation. This yields the
|
||||||
// shallow result we are looking for -- that is, what specific impl.
|
// shallow result we are looking for -- that is, what specific impl.
|
||||||
let typer = NormalizingClosureTyper::new(tcx);
|
let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables);
|
||||||
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
|
let mut selcx = traits::SelectionContext::new(&infcx, &infcx);
|
||||||
|
|
||||||
let obligation =
|
let obligation =
|
||||||
traits::Obligation::new(traits::ObligationCause::misc(span, ast::DUMMY_NODE_ID),
|
traits::Obligation::new(traits::ObligationCause::misc(span, ast::DUMMY_NODE_ID),
|
||||||
trait_ref.to_poly_trait_predicate());
|
trait_ref.to_poly_trait_predicate());
|
||||||
|
@ -1019,9 +1020,8 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
predicates);
|
predicates);
|
||||||
|
|
||||||
let tcx = ccx.tcx();
|
let tcx = ccx.tcx();
|
||||||
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false);
|
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, true);
|
||||||
let typer = NormalizingClosureTyper::new(tcx);
|
let mut selcx = traits::SelectionContext::new(&infcx, &infcx);
|
||||||
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
|
|
||||||
let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut();
|
let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut();
|
||||||
let cause = traits::ObligationCause::dummy();
|
let cause = traits::ObligationCause::dummy();
|
||||||
let traits::Normalized { value: predicates, obligations } =
|
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()
|
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<ty::ClosureKind>
|
|
||||||
{
|
|
||||||
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<Vec<ty::ClosureUpvar<'tcx>>>
|
|
||||||
{
|
|
||||||
// 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,
|
pub fn drain_fulfillment_cx_or_panic<'a,'tcx,T>(span: Span,
|
||||||
infcx: &infer::InferCtxt<'a,'tcx>,
|
infcx: &infer::InferCtxt<'a,'tcx>,
|
||||||
fulfill_cx: &mut traits::FulfillmentContext<'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={:?})",
|
debug!("drain_fulfillment_cx(result={:?})",
|
||||||
result);
|
result);
|
||||||
|
// this is stupid but temporary
|
||||||
|
let typer: &ClosureTyper<'tcx> = infcx;
|
||||||
// In principle, we only need to do this so long as `result`
|
// In principle, we only need to do this so long as `result`
|
||||||
// contains unbound type parameters. It could be a slight
|
// contains unbound type parameters. It could be a slight
|
||||||
// optimization to stop iterating early.
|
// 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(()) => { }
|
Ok(()) => { }
|
||||||
Err(errors) => {
|
Err(errors) => {
|
||||||
return Err(errors);
|
return Err(errors);
|
||||||
|
|
|
@ -26,9 +26,10 @@ use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType};
|
||||||
use metadata::csearch;
|
use metadata::csearch;
|
||||||
use middle::pat_util;
|
use middle::pat_util;
|
||||||
use middle::subst::{self, Substs};
|
use middle::subst::{self, Substs};
|
||||||
|
use middle::infer;
|
||||||
use rustc::ast_map;
|
use rustc::ast_map;
|
||||||
use trans::{type_of, adt, machine, monomorphize};
|
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::_match::{BindingInfo, TrByCopy, TrByMove, TrByRef};
|
||||||
use trans::type_::Type;
|
use trans::type_::Type;
|
||||||
use middle::ty::{self, Ty, ClosureTyper};
|
use middle::ty::{self, Ty, ClosureTyper};
|
||||||
|
@ -287,8 +288,8 @@ impl<'tcx> TypeMap<'tcx> {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ty::TyClosure(def_id, substs) => {
|
ty::TyClosure(def_id, substs) => {
|
||||||
let typer = NormalizingClosureTyper::new(cx.tcx());
|
let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables);
|
||||||
let closure_ty = typer.closure_type(def_id, substs);
|
let closure_ty = infcx.closure_type(def_id, substs);
|
||||||
self.get_unique_type_id_of_closure_type(cx,
|
self.get_unique_type_id_of_closure_type(cx,
|
||||||
closure_ty,
|
closure_ty,
|
||||||
&mut unique_type_id);
|
&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)
|
subroutine_type_metadata(cx, unique_type_id, &barefnty.sig, usage_site_span)
|
||||||
}
|
}
|
||||||
ty::TyClosure(def_id, substs) => {
|
ty::TyClosure(def_id, substs) => {
|
||||||
let typer = NormalizingClosureTyper::new(cx.tcx());
|
let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables);
|
||||||
let sig = typer.closure_type(def_id, substs).sig;
|
let sig = infcx.closure_type(def_id, substs).sig;
|
||||||
subroutine_type_metadata(cx, unique_type_id, &sig, usage_site_span)
|
subroutine_type_metadata(cx, unique_type_id, &sig, usage_site_span)
|
||||||
}
|
}
|
||||||
ty::TyStruct(def_id, substs) => {
|
ty::TyStruct(def_id, substs) => {
|
||||||
|
|
|
@ -21,10 +21,10 @@
|
||||||
//! * When in doubt, define.
|
//! * When in doubt, define.
|
||||||
use llvm::{self, ValueRef};
|
use llvm::{self, ValueRef};
|
||||||
use middle::ty::{self, ClosureTyper};
|
use middle::ty::{self, ClosureTyper};
|
||||||
|
use middle::infer;
|
||||||
use syntax::abi;
|
use syntax::abi;
|
||||||
use trans::attributes;
|
use trans::attributes;
|
||||||
use trans::base;
|
use trans::base;
|
||||||
use trans::common;
|
|
||||||
use trans::context::CrateContext;
|
use trans::context::CrateContext;
|
||||||
use trans::monomorphize;
|
use trans::monomorphize;
|
||||||
use trans::type_::Type;
|
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)
|
(&f.sig, f.abi, None)
|
||||||
}
|
}
|
||||||
ty::TyClosure(closure_did, substs) => {
|
ty::TyClosure(closure_did, substs) => {
|
||||||
let typer = common::NormalizingClosureTyper::new(ccx.tcx());
|
let infcx = infer::normalizing_infer_ctxt(ccx.tcx(), &ccx.tcx().tables);
|
||||||
function_type = typer.closure_type(closure_did, substs);
|
function_type = infcx.closure_type(closure_did, substs);
|
||||||
let self_type = base::self_type_for_closure(ccx, closure_did, fn_type);
|
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);
|
let llenvironment_type = type_of::type_of_explicit_arg(ccx, self_type);
|
||||||
debug!("declare_rust_fn function_type={:?} self_type={:?}",
|
debug!("declare_rust_fn function_type={:?} self_type={:?}",
|
||||||
|
|
|
@ -324,9 +324,8 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
|
||||||
// FIXME(#20304) -- cache
|
// FIXME(#20304) -- cache
|
||||||
// NOTE: @jroesch
|
// NOTE: @jroesch
|
||||||
// Here is of an example where we do not use a param_env but use a typer instead.
|
// 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 infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables);
|
||||||
let typer = NormalizingClosureTyper::new(tcx);
|
let mut selcx = traits::SelectionContext::new(&infcx, &infcx);
|
||||||
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
|
|
||||||
let cause = traits::ObligationCause::dummy();
|
let cause = traits::ObligationCause::dummy();
|
||||||
let traits::Normalized { value: result, obligations } =
|
let traits::Normalized { value: result, obligations } =
|
||||||
traits::normalize(&mut selcx, cause, &value);
|
traits::normalize(&mut selcx, cause, &value);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue