@@ -143,6 +143,9 @@ pub(crate) struct InferenceTable<'a> {
143
143
var_unification_table : ChalkInferenceTable ,
144
144
type_variable_table : Vec < TypeVariableFlags > ,
145
145
pending_obligations : Vec < Canonicalized < InEnvironment < Goal > > > ,
146
+ /// Double buffer used in [`Self::resolve_obligations_as_possible`] to cut down on
147
+ /// temporary allocations.
148
+ resolve_obligations_buffer : Vec < Canonicalized < InEnvironment < Goal > > > ,
146
149
}
147
150
148
151
pub ( crate ) struct InferenceTableSnapshot {
@@ -159,6 +162,7 @@ impl<'a> InferenceTable<'a> {
159
162
var_unification_table : ChalkInferenceTable :: new ( ) ,
160
163
type_variable_table : Vec :: new ( ) ,
161
164
pending_obligations : Vec :: new ( ) ,
165
+ resolve_obligations_buffer : Vec :: new ( ) ,
162
166
}
163
167
}
164
168
@@ -510,10 +514,10 @@ impl<'a> InferenceTable<'a> {
510
514
pub ( crate ) fn resolve_obligations_as_possible ( & mut self ) {
511
515
let _span = profile:: span ( "resolve_obligations_as_possible" ) ;
512
516
let mut changed = true ;
513
- let mut obligations = Vec :: new ( ) ;
514
- while changed {
515
- changed = false ;
517
+ let mut obligations = mem:: take ( & mut self . resolve_obligations_buffer ) ;
518
+ while mem:: take ( & mut changed) {
516
519
mem:: swap ( & mut self . pending_obligations , & mut obligations) ;
520
+
517
521
for canonicalized in obligations. drain ( ..) {
518
522
if !self . check_changed ( & canonicalized) {
519
523
self . pending_obligations . push ( canonicalized) ;
@@ -528,6 +532,8 @@ impl<'a> InferenceTable<'a> {
528
532
self . register_obligation_in_env ( uncanonical) ;
529
533
}
530
534
}
535
+ self . resolve_obligations_buffer = obligations;
536
+ self . resolve_obligations_buffer . clear ( ) ;
531
537
}
532
538
533
539
pub ( crate ) fn fudge_inference < T : TypeFoldable < Interner > > (
0 commit comments