Skip to content

Commit 16cacbe

Browse files
committed
Auto merge of #27866 - arielb1:really-fast-reject, r=nikomatsakis
also, use the right caching logic for type_moves_by_default (this was broken by @jroesch). ``` before: 593.10user 5.21system 7:51.41elapsed 126%CPU (0avgtext+0avgdata 1150016maxresident)k after: 567.03user 4.00system 7:28.23elapsed 127%CPU (0avgtext+0avgdata 1133112maxresident)k ``` A nice 4.5% improvement. For reference, on the last run LLVM takes 429.267s, which is 75% - hopefully this can be reduced. I think the regression since #27751 is because of the wf patch - need to investigate it through. r? @nikomatsakis
2 parents 4c0ffc0 + 13809ff commit 16cacbe

File tree

8 files changed

+86
-24
lines changed

8 files changed

+86
-24
lines changed

src/librustc/middle/fast_reject.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,13 @@ pub fn simplify_type(tcx: &ty::ctxt,
8585
ty::TyBareFn(_, ref f) => {
8686
Some(FunctionSimplifiedType(f.sig.0.inputs.len()))
8787
}
88-
ty::TyProjection(_) => {
89-
None
90-
}
91-
ty::TyParam(_) => {
88+
ty::TyProjection(_) | ty::TyParam(_) => {
9289
if can_simplify_params {
90+
// In normalized types, projections don't unify with
91+
// anything. when lazy normalization happens, this
92+
// will change. It would still be nice to have a way
93+
// to deal with known-not-to-unify-with-anything
94+
// projections (e.g. the likes of <__S as Encoder>::Error).
9395
Some(ParameterSimplifiedType)
9496
} else {
9597
None

src/librustc/middle/infer/higher_ranked/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ pub fn plug_leaks<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
614614
snapshot: &CombinedSnapshot,
615615
value: &T)
616616
-> T
617-
where T : TypeFoldable<'tcx>
617+
where T : TypeFoldable<'tcx> + ty::HasTypeFlags
618618
{
619619
debug_assert!(leak_check(infcx, &skol_map, snapshot).is_ok());
620620

src/librustc/middle/infer/mod.rs

+16-5
Original file line numberDiff line numberDiff line change
@@ -985,7 +985,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
985985
snapshot: &CombinedSnapshot,
986986
value: &T)
987987
-> T
988-
where T : TypeFoldable<'tcx>
988+
where T : TypeFoldable<'tcx> + HasTypeFlags
989989
{
990990
/*! See `higher_ranked::plug_leaks` */
991991

@@ -1256,7 +1256,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
12561256
}
12571257
}
12581258

1259-
pub fn resolve_type_vars_if_possible<T:TypeFoldable<'tcx>>(&self, value: &T) -> T {
1259+
pub fn resolve_type_vars_if_possible<T>(&self, value: &T) -> T
1260+
where T: TypeFoldable<'tcx> + HasTypeFlags
1261+
{
12601262
/*!
12611263
* Where possible, replaces type/int/float variables in
12621264
* `value` with their final value. Note that region variables
@@ -1266,6 +1268,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
12661268
* at will.
12671269
*/
12681270

1271+
if !value.needs_infer() {
1272+
return value.clone(); // avoid duplicated subst-folding
1273+
}
12691274
let mut r = resolve::OpportunisticTypeResolver::new(self);
12701275
value.fold_with(&mut r)
12711276
}
@@ -1456,9 +1461,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
14561461

14571462
pub fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
14581463
let ty = self.resolve_type_vars_if_possible(&ty);
1459-
!traits::type_known_to_meet_builtin_bound(self, ty, ty::BoundCopy, span)
1460-
// FIXME(@jroesch): should be able to use:
1461-
// ty.moves_by_default(&self.parameter_environment, span)
1464+
if ty.needs_infer() {
1465+
// this can get called from typeck (by euv), and moves_by_default
1466+
// rightly refuses to work with inference variables, but
1467+
// moves_by_default has a cache, which we want to use in other
1468+
// cases.
1469+
!traits::type_known_to_meet_builtin_bound(self, ty, ty::BoundCopy, span)
1470+
} else {
1471+
ty.moves_by_default(&self.parameter_environment, span)
1472+
}
14621473
}
14631474

14641475
pub fn node_method_ty(&self, method_call: ty::MethodCall)

src/librustc/middle/traits/error_reporting.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ fn report_on_unimplemented<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
160160
pub fn report_overflow_error<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
161161
obligation: &Obligation<'tcx, T>)
162162
-> !
163-
where T: fmt::Display + TypeFoldable<'tcx>
163+
where T: fmt::Display + TypeFoldable<'tcx> + HasTypeFlags
164164
{
165165
let predicate =
166166
infcx.resolve_type_vars_if_possible(&obligation.predicate);

src/librustc/middle/traits/fulfill.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,10 @@ use middle::infer::InferCtxt;
1212
use middle::ty::{self, RegionEscape, Ty, HasTypeFlags};
1313
use middle::wf;
1414

15-
use std::collections::HashSet;
1615
use std::fmt;
1716
use syntax::ast;
1817
use util::common::ErrorReported;
19-
use util::nodemap::NodeMap;
18+
use util::nodemap::{FnvHashSet, NodeMap};
2019

2120
use super::CodeAmbiguity;
2221
use super::CodeProjectionError;
@@ -33,7 +32,7 @@ use super::Unimplemented;
3332
use super::util::predicate_for_builtin_bound;
3433

3534
pub struct FulfilledPredicates<'tcx> {
36-
set: HashSet<(RFC1214Warning, ty::Predicate<'tcx>)>
35+
set: FnvHashSet<(RFC1214Warning, ty::Predicate<'tcx>)>
3736
}
3837

3938
/// The fulfillment context is used to drive trait resolution. It
@@ -540,7 +539,7 @@ fn register_region_obligation<'tcx>(t_a: Ty<'tcx>,
540539
impl<'tcx> FulfilledPredicates<'tcx> {
541540
pub fn new() -> FulfilledPredicates<'tcx> {
542541
FulfilledPredicates {
543-
set: HashSet::new()
542+
set: FnvHashSet()
544543
}
545544
}
546545

src/librustc/middle/traits/project.rs

+7
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,13 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> {
927927
}
928928
}
929929

930+
impl<'tcx, T: HasTypeFlags> HasTypeFlags for Normalized<'tcx, T> {
931+
fn has_type_flags(&self, flags: ty::TypeFlags) -> bool {
932+
self.value.has_type_flags(flags) ||
933+
self.obligations.has_type_flags(flags)
934+
}
935+
}
936+
930937
impl<'tcx, T:fmt::Debug> fmt::Debug for Normalized<'tcx, T> {
931938
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
932939
write!(f, "Normalized({:?},{:?})",

src/librustc/middle/ty.rs

+50-7
Original file line numberDiff line numberDiff line change
@@ -3192,6 +3192,8 @@ impl<'tcx> TraitDef<'tcx> {
31923192
}
31933193
}
31943194

3195+
/// Iterate over every impl that could possibly match the
3196+
/// self-type `self_ty`.
31953197
pub fn for_each_relevant_impl<F: FnMut(DefId)>(&self,
31963198
tcx: &ctxt<'tcx>,
31973199
self_ty: Ty<'tcx>,
@@ -3203,18 +3205,29 @@ impl<'tcx> TraitDef<'tcx> {
32033205
f(impl_def_id);
32043206
}
32053207

3206-
if let Some(simp) = fast_reject::simplify_type(tcx, self_ty, false) {
3208+
// simplify_type(.., false) basically replaces type parameters and
3209+
// projections with infer-variables. This is, of course, done on
3210+
// the impl trait-ref when it is instantiated, but not on the
3211+
// predicate trait-ref which is passed here.
3212+
//
3213+
// for example, if we match `S: Copy` against an impl like
3214+
// `impl<T:Copy> Copy for Option<T>`, we replace the type variable
3215+
// in `Option<T>` with an infer variable, to `Option<_>` (this
3216+
// doesn't actually change fast_reject output), but we don't
3217+
// replace `S` with anything - this impl of course can't be
3218+
// selected, and as there are hundreds of similar impls,
3219+
// considering them would significantly harm performance.
3220+
if let Some(simp) = fast_reject::simplify_type(tcx, self_ty, true) {
32073221
if let Some(impls) = self.nonblanket_impls.borrow().get(&simp) {
32083222
for &impl_def_id in impls {
32093223
f(impl_def_id);
32103224
}
3211-
return; // we don't need to process the other non-blanket impls
32123225
}
3213-
}
3214-
3215-
for v in self.nonblanket_impls.borrow().values() {
3216-
for &impl_def_id in v {
3217-
f(impl_def_id);
3226+
} else {
3227+
for v in self.nonblanket_impls.borrow().values() {
3228+
for &impl_def_id in v {
3229+
f(impl_def_id);
3230+
}
32183231
}
32193232
}
32203233
}
@@ -7267,6 +7280,24 @@ impl<'tcx,T:HasTypeFlags> HasTypeFlags for VecPerParamSpace<T> {
72677280
}
72687281
}
72697282

7283+
impl HasTypeFlags for abi::Abi {
7284+
fn has_type_flags(&self, _flags: TypeFlags) -> bool {
7285+
false
7286+
}
7287+
}
7288+
7289+
impl HasTypeFlags for ast::Unsafety {
7290+
fn has_type_flags(&self, _flags: TypeFlags) -> bool {
7291+
false
7292+
}
7293+
}
7294+
7295+
impl HasTypeFlags for BuiltinBounds {
7296+
fn has_type_flags(&self, _flags: TypeFlags) -> bool {
7297+
false
7298+
}
7299+
}
7300+
72707301
impl<'tcx> HasTypeFlags for ClosureTy<'tcx> {
72717302
fn has_type_flags(&self, flags: TypeFlags) -> bool {
72727303
self.sig.has_type_flags(flags)
@@ -7279,6 +7310,12 @@ impl<'tcx> HasTypeFlags for ClosureUpvar<'tcx> {
72797310
}
72807311
}
72817312

7313+
impl<'tcx> HasTypeFlags for ExistentialBounds<'tcx> {
7314+
fn has_type_flags(&self, flags: TypeFlags) -> bool {
7315+
self.projection_bounds.has_type_flags(flags)
7316+
}
7317+
}
7318+
72827319
impl<'tcx> HasTypeFlags for ty::InstantiatedPredicates<'tcx> {
72837320
fn has_type_flags(&self, flags: TypeFlags) -> bool {
72847321
self.predicates.has_type_flags(flags)
@@ -7354,6 +7391,12 @@ impl<'tcx> HasTypeFlags for Ty<'tcx> {
73547391
}
73557392
}
73567393

7394+
impl<'tcx> HasTypeFlags for TypeAndMut<'tcx> {
7395+
fn has_type_flags(&self, flags: TypeFlags) -> bool {
7396+
self.ty.has_type_flags(flags)
7397+
}
7398+
}
7399+
73577400
impl<'tcx> HasTypeFlags for TraitRef<'tcx> {
73587401
fn has_type_flags(&self, flags: TypeFlags) -> bool {
73597402
self.substs.has_type_flags(flags)

src/librustc/middle/ty_relate/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
//! type equality, etc.
1515
1616
use middle::subst::{ErasedRegions, NonerasedRegions, ParamSpace, Substs};
17-
use middle::ty::{self, Ty, TypeError};
17+
use middle::ty::{self, HasTypeFlags, Ty, TypeError};
1818
use middle::ty_fold::TypeFoldable;
1919
use std::rc::Rc;
2020
use syntax::abi;
@@ -78,7 +78,7 @@ pub trait TypeRelation<'a,'tcx> : Sized {
7878
where T: Relate<'a,'tcx>;
7979
}
8080

81-
pub trait Relate<'a,'tcx>: TypeFoldable<'tcx> {
81+
pub trait Relate<'a,'tcx>: TypeFoldable<'tcx> + HasTypeFlags {
8282
fn relate<R:TypeRelation<'a,'tcx>>(relation: &mut R,
8383
a: &Self,
8484
b: &Self)

0 commit comments

Comments
 (0)