@@ -41,6 +41,7 @@ use rustc_middle::ty::subst::{GenericArgKind, Subst, SubstsRef};
4141use rustc_middle:: ty:: { self , PolyProjectionPredicate , ToPolyTraitRef , ToPredicate } ;
4242use rustc_middle:: ty:: { Ty , TyCtxt , TypeFoldable } ;
4343use rustc_span:: symbol:: sym;
44+ use smallvec:: SmallVec ;
4445
4546use std:: cell:: { Cell , RefCell } ;
4647use std:: cmp;
@@ -1360,7 +1361,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13601361 fn match_projection_obligation_against_definition_bounds (
13611362 & mut self ,
13621363 obligation : & TraitObligation < ' tcx > ,
1363- ) -> smallvec :: SmallVec < [ usize ; 2 ] > {
1364+ ) -> SmallVec < [ usize ; 2 ] > {
13641365 let poly_trait_predicate = self . infcx ( ) . resolve_vars_if_possible ( obligation. predicate ) ;
13651366 let placeholder_trait_predicate =
13661367 self . infcx ( ) . replace_bound_vars_with_placeholders ( poly_trait_predicate) ;
@@ -2016,7 +2017,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
20162017 recursion_depth : usize ,
20172018 trait_def_id : DefId ,
20182019 types : ty:: Binder < ' tcx , Vec < Ty < ' tcx > > > ,
2019- ) -> Vec < PredicateObligation < ' tcx > > {
2020+ out : & mut Vec < PredicateObligation < ' tcx > > ,
2021+ ) {
20202022 // Because the types were potentially derived from
20212023 // higher-ranked obligations they may reference late-bound
20222024 // regions. For example, `for<'a> Foo<&'a i32> : Copy` would
@@ -2030,17 +2032,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
20302032 // `for<'a> &'a i32` becomes `&0 i32`.
20312033 // 2. Produce something like `&'0 i32 : Copy`
20322034 // 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.
20342038 types
20352039 . as_ref ( )
20362040 . skip_binder ( ) // binder moved -\
20372041 . iter ( )
2038- . flat_map ( |ty| {
2042+ . for_each ( |ty| {
20392043 let ty: ty:: Binder < ' tcx , Ty < ' tcx > > = types. rebind ( * ty) ; // <----/
20402044
20412045 self . infcx . commit_unconditionally ( |_| {
20422046 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 } =
20442049 ensure_sufficient_stack ( || {
20452050 project:: normalize_with_depth (
20462051 self ,
@@ -2050,6 +2055,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
20502055 placeholder_ty,
20512056 )
20522057 } ) ;
2058+ out. extend ( obligations) ;
20532059 let placeholder_obligation = predicate_for_trait_def (
20542060 self . tcx ( ) ,
20552061 param_env,
@@ -2059,11 +2065,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
20592065 normalized_ty,
20602066 & [ ] ,
20612067 ) ;
2062- obligations. push ( placeholder_obligation) ;
2063- obligations
2068+ out. push ( placeholder_obligation) ;
20642069 } )
2065- } )
2066- . collect ( )
2070+ } ) ;
20672071 }
20682072
20692073 ///////////////////////////////////////////////////////////////////////////
@@ -2337,7 +2341,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
23372341 def_id : DefId , // of impl or trait
23382342 substs : SubstsRef < ' tcx > , // for impl or trait
23392343 parent_trait_pred : ty:: Binder < ' tcx , ty:: TraitPredicate < ' tcx > > ,
2340- ) -> Vec < PredicateObligation < ' tcx > > {
2344+ out : & mut Vec < PredicateObligation < ' tcx > > ,
2345+ ) {
23412346 let tcx = self . tcx ( ) ;
23422347
23432348 // To allow for one-pass evaluation of the nested obligation,
@@ -2357,7 +2362,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
23572362 let predicates = tcx. predicates_of ( def_id) ;
23582363 debug ! ( ?predicates) ;
23592364 assert_eq ! ( predicates. parent, None ) ;
2360- let mut obligations = Vec :: with_capacity ( predicates. predicates . len ( ) ) ;
2365+ out . reserve ( predicates. predicates . len ( ) ) ;
23612366 let parent_code = cause. clone_code ( ) ;
23622367 for ( predicate, span) in predicates. predicates {
23632368 let span = * span;
@@ -2375,12 +2380,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
23752380 cause. clone ( ) ,
23762381 recursion_depth,
23772382 predicate. subst ( tcx, substs) ,
2378- & mut obligations ,
2383+ out ,
23792384 ) ;
2380- obligations . push ( Obligation { cause, recursion_depth, param_env, predicate } ) ;
2385+ out . push ( Obligation { cause, recursion_depth, param_env, predicate } ) ;
23812386 }
2382-
2383- obligations
23842387 }
23852388}
23862389
0 commit comments