@@ -41,6 +41,7 @@ use rustc_middle::ty::subst::{GenericArgKind, Subst, SubstsRef};
41
41
use rustc_middle:: ty:: { self , PolyProjectionPredicate , ToPolyTraitRef , ToPredicate } ;
42
42
use rustc_middle:: ty:: { Ty , TyCtxt , TypeFoldable } ;
43
43
use rustc_span:: symbol:: sym;
44
+ use smallvec:: SmallVec ;
44
45
45
46
use std:: cell:: { Cell , RefCell } ;
46
47
use std:: cmp;
@@ -1360,7 +1361,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1360
1361
fn match_projection_obligation_against_definition_bounds (
1361
1362
& mut self ,
1362
1363
obligation : & TraitObligation < ' tcx > ,
1363
- ) -> smallvec :: SmallVec < [ usize ; 2 ] > {
1364
+ ) -> SmallVec < [ usize ; 2 ] > {
1364
1365
let poly_trait_predicate = self . infcx ( ) . resolve_vars_if_possible ( obligation. predicate ) ;
1365
1366
let placeholder_trait_predicate =
1366
1367
self . infcx ( ) . replace_bound_vars_with_placeholders ( poly_trait_predicate) ;
@@ -2016,7 +2017,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
2016
2017
recursion_depth : usize ,
2017
2018
trait_def_id : DefId ,
2018
2019
types : ty:: Binder < ' tcx , Vec < Ty < ' tcx > > > ,
2019
- ) -> Vec < PredicateObligation < ' tcx > > {
2020
+ out : & mut Vec < PredicateObligation < ' tcx > > ,
2021
+ ) {
2020
2022
// Because the types were potentially derived from
2021
2023
// higher-ranked obligations they may reference late-bound
2022
2024
// regions. For example, `for<'a> Foo<&'a i32> : Copy` would
@@ -2030,17 +2032,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
2030
2032
// `for<'a> &'a i32` becomes `&0 i32`.
2031
2033
// 2. Produce something like `&'0 i32 : Copy`
2032
2034
// 3. Re-bind the regions back to `for<'a> &'a i32 : Copy`
2033
-
2035
+ //
2036
+ // This function is called enough that it's better to append to a `&mut
2037
+ // Vec` than return a `Vec`, to avoid allocations.
2034
2038
types
2035
2039
. as_ref ( )
2036
2040
. skip_binder ( ) // binder moved -\
2037
2041
. iter ( )
2038
- . flat_map ( |ty| {
2042
+ . for_each ( |ty| {
2039
2043
let ty: ty:: Binder < ' tcx , Ty < ' tcx > > = types. rebind ( * ty) ; // <----/
2040
2044
2041
2045
self . infcx . commit_unconditionally ( |_| {
2042
2046
let placeholder_ty = self . infcx . replace_bound_vars_with_placeholders ( ty) ;
2043
- let Normalized { value : normalized_ty, mut obligations } =
2047
+ // `obligations` is almost always empty.
2048
+ let Normalized { value : normalized_ty, obligations } =
2044
2049
ensure_sufficient_stack ( || {
2045
2050
project:: normalize_with_depth (
2046
2051
self ,
@@ -2050,6 +2055,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
2050
2055
placeholder_ty,
2051
2056
)
2052
2057
} ) ;
2058
+ out. extend ( obligations) ;
2053
2059
let placeholder_obligation = predicate_for_trait_def (
2054
2060
self . tcx ( ) ,
2055
2061
param_env,
@@ -2059,11 +2065,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
2059
2065
normalized_ty,
2060
2066
& [ ] ,
2061
2067
) ;
2062
- obligations. push ( placeholder_obligation) ;
2063
- obligations
2068
+ out. push ( placeholder_obligation) ;
2064
2069
} )
2065
- } )
2066
- . collect ( )
2070
+ } ) ;
2067
2071
}
2068
2072
2069
2073
///////////////////////////////////////////////////////////////////////////
@@ -2337,7 +2341,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
2337
2341
def_id : DefId , // of impl or trait
2338
2342
substs : SubstsRef < ' tcx > , // for impl or trait
2339
2343
parent_trait_pred : ty:: Binder < ' tcx , ty:: TraitPredicate < ' tcx > > ,
2340
- ) -> Vec < PredicateObligation < ' tcx > > {
2344
+ out : & mut Vec < PredicateObligation < ' tcx > > ,
2345
+ ) {
2341
2346
let tcx = self . tcx ( ) ;
2342
2347
2343
2348
// To allow for one-pass evaluation of the nested obligation,
@@ -2357,7 +2362,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
2357
2362
let predicates = tcx. predicates_of ( def_id) ;
2358
2363
debug ! ( ?predicates) ;
2359
2364
assert_eq ! ( predicates. parent, None ) ;
2360
- let mut obligations = Vec :: with_capacity ( predicates. predicates . len ( ) ) ;
2365
+ out . reserve ( predicates. predicates . len ( ) ) ;
2361
2366
let parent_code = cause. clone_code ( ) ;
2362
2367
for ( predicate, span) in predicates. predicates {
2363
2368
let span = * span;
@@ -2375,12 +2380,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
2375
2380
cause. clone ( ) ,
2376
2381
recursion_depth,
2377
2382
predicate. subst ( tcx, substs) ,
2378
- & mut obligations ,
2383
+ out ,
2379
2384
) ;
2380
- obligations . push ( Obligation { cause, recursion_depth, param_env, predicate } ) ;
2385
+ out . push ( Obligation { cause, recursion_depth, param_env, predicate } ) ;
2381
2386
}
2382
-
2383
- obligations
2384
2387
}
2385
2388
}
2386
2389
0 commit comments