add a fast-path to resolve_type_vars_if_possible
this avoids needless substituting before: 577.76user 4.27system 7:36.13elapsed 127%CPU (0avgtext+0avgdata 1141608maxresident)k after: 573.01user 4.04system 7:33.86elapsed 127%CPU (0avgtext+0avgdata 1141656maxresident)k
This commit is contained in:
parent
96e6b2fef8
commit
8aeaaac654
6 changed files with 48 additions and 6 deletions
|
|
@ -614,7 +614,7 @@ pub fn plug_leaks<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
|
|||
snapshot: &CombinedSnapshot,
|
||||
value: &T)
|
||||
-> T
|
||||
where T : TypeFoldable<'tcx>
|
||||
where T : TypeFoldable<'tcx> + ty::HasTypeFlags
|
||||
{
|
||||
debug_assert!(leak_check(infcx, &skol_map, snapshot).is_ok());
|
||||
|
||||
|
|
|
|||
|
|
@ -985,7 +985,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
snapshot: &CombinedSnapshot,
|
||||
value: &T)
|
||||
-> T
|
||||
where T : TypeFoldable<'tcx>
|
||||
where T : TypeFoldable<'tcx> + HasTypeFlags
|
||||
{
|
||||
/*! See `higher_ranked::plug_leaks` */
|
||||
|
||||
|
|
@ -1256,7 +1256,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn resolve_type_vars_if_possible<T:TypeFoldable<'tcx>>(&self, value: &T) -> T {
|
||||
pub fn resolve_type_vars_if_possible<T>(&self, value: &T) -> T
|
||||
where T: TypeFoldable<'tcx> + HasTypeFlags
|
||||
{
|
||||
/*!
|
||||
* Where possible, replaces type/int/float variables in
|
||||
* `value` with their final value. Note that region variables
|
||||
|
|
@ -1266,6 +1268,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
* at will.
|
||||
*/
|
||||
|
||||
if !value.needs_infer() {
|
||||
return value.clone(); // avoid duplicated subst-folding
|
||||
}
|
||||
let mut r = resolve::OpportunisticTypeResolver::new(self);
|
||||
value.fold_with(&mut r)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ fn report_on_unimplemented<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
|||
pub fn report_overflow_error<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
obligation: &Obligation<'tcx, T>)
|
||||
-> !
|
||||
where T: fmt::Display + TypeFoldable<'tcx>
|
||||
where T: fmt::Display + TypeFoldable<'tcx> + HasTypeFlags
|
||||
{
|
||||
let predicate =
|
||||
infcx.resolve_type_vars_if_possible(&obligation.predicate);
|
||||
|
|
|
|||
|
|
@ -927,6 +927,13 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T: HasTypeFlags> HasTypeFlags for Normalized<'tcx, T> {
|
||||
fn has_type_flags(&self, flags: ty::TypeFlags) -> bool {
|
||||
self.value.has_type_flags(flags) ||
|
||||
self.obligations.has_type_flags(flags)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T:fmt::Debug> fmt::Debug for Normalized<'tcx, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Normalized({:?},{:?})",
|
||||
|
|
|
|||
|
|
@ -7280,6 +7280,24 @@ impl<'tcx,T:HasTypeFlags> HasTypeFlags for VecPerParamSpace<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl HasTypeFlags for abi::Abi {
|
||||
fn has_type_flags(&self, _flags: TypeFlags) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl HasTypeFlags for ast::Unsafety {
|
||||
fn has_type_flags(&self, _flags: TypeFlags) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl HasTypeFlags for BuiltinBounds {
|
||||
fn has_type_flags(&self, _flags: TypeFlags) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> HasTypeFlags for ClosureTy<'tcx> {
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||
self.sig.has_type_flags(flags)
|
||||
|
|
@ -7292,6 +7310,12 @@ impl<'tcx> HasTypeFlags for ClosureUpvar<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> HasTypeFlags for ExistentialBounds<'tcx> {
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||
self.projection_bounds.has_type_flags(flags)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> HasTypeFlags for ty::InstantiatedPredicates<'tcx> {
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||
self.predicates.has_type_flags(flags)
|
||||
|
|
@ -7367,6 +7391,12 @@ impl<'tcx> HasTypeFlags for Ty<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> HasTypeFlags for TypeAndMut<'tcx> {
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||
self.ty.has_type_flags(flags)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> HasTypeFlags for TraitRef<'tcx> {
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||
self.substs.has_type_flags(flags)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
//! type equality, etc.
|
||||
|
||||
use middle::subst::{ErasedRegions, NonerasedRegions, ParamSpace, Substs};
|
||||
use middle::ty::{self, Ty, TypeError};
|
||||
use middle::ty::{self, HasTypeFlags, Ty, TypeError};
|
||||
use middle::ty_fold::TypeFoldable;
|
||||
use std::rc::Rc;
|
||||
use syntax::abi;
|
||||
|
|
@ -78,7 +78,7 @@ pub trait TypeRelation<'a,'tcx> : Sized {
|
|||
where T: Relate<'a,'tcx>;
|
||||
}
|
||||
|
||||
pub trait Relate<'a,'tcx>: TypeFoldable<'tcx> {
|
||||
pub trait Relate<'a,'tcx>: TypeFoldable<'tcx> + HasTypeFlags {
|
||||
fn relate<R:TypeRelation<'a,'tcx>>(relation: &mut R,
|
||||
a: &Self,
|
||||
b: &Self)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue