@@ -143,6 +143,9 @@ pub(crate) struct InferenceTable<'a> {
143143 var_unification_table : ChalkInferenceTable ,
144144 type_variable_table : Vec < TypeVariableFlags > ,
145145 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 > > > ,
146149}
147150
148151pub ( crate ) struct InferenceTableSnapshot {
@@ -159,6 +162,7 @@ impl<'a> InferenceTable<'a> {
159162 var_unification_table : ChalkInferenceTable :: new ( ) ,
160163 type_variable_table : Vec :: new ( ) ,
161164 pending_obligations : Vec :: new ( ) ,
165+ resolve_obligations_buffer : Vec :: new ( ) ,
162166 }
163167 }
164168
@@ -510,10 +514,10 @@ impl<'a> InferenceTable<'a> {
510514 pub ( crate ) fn resolve_obligations_as_possible ( & mut self ) {
511515 let _span = profile:: span ( "resolve_obligations_as_possible" ) ;
512516 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) {
516519 mem:: swap ( & mut self . pending_obligations , & mut obligations) ;
520+
517521 for canonicalized in obligations. drain ( ..) {
518522 if !self . check_changed ( & canonicalized) {
519523 self . pending_obligations . push ( canonicalized) ;
@@ -528,6 +532,8 @@ impl<'a> InferenceTable<'a> {
528532 self . register_obligation_in_env ( uncanonical) ;
529533 }
530534 }
535+ self . resolve_obligations_buffer = obligations;
536+ self . resolve_obligations_buffer . clear ( ) ;
531537 }
532538
533539 pub ( crate ) fn fudge_inference < T : TypeFoldable < Interner > > (
0 commit comments