@@ -133,37 +133,35 @@ where
133133 }
134134
135135 let initial_size = self . obligations . len ( ) ;
136- let iter = iter . into_iter ( ) ;
136+ let current_capacity = self . obligations . capacity ( ) ;
137137 let expected_new = iter. len ( ) ;
138138 let combined_size = initial_size + expected_new;
139139
140- if combined_size <= 16 || combined_size < initial_size . next_power_of_two ( ) {
140+ if combined_size <= 16 || combined_size <= current_capacity {
141141 // small case/not crossing a power of two. don't bother with dedup
142142 self . obligations . extend ( iter. map ( Cow :: into_owned) ) ;
143143 } else {
144144 // crossing power of two threshold. this would incur a vec growth anyway if we didn't do
145145 // anything. piggyback a dedup on that
146- let obligations = std:: mem:: take ( self . obligations ) ;
147-
148- let mut seen = FxHashMap :: default ( ) ;
149- seen. reserve ( initial_size) ;
150-
151- * self . obligations = obligations
152- . into_iter ( )
153- . map ( Cow :: Owned )
154- . chain ( iter)
155- . filter_map ( |obligation| {
156- match seen. raw_entry_mut ( ) . from_key ( obligation. borrow ( ) ) {
157- RawEntryMut :: Occupied ( ..) => {
158- return None ;
159- }
160- RawEntryMut :: Vacant ( vacant) => {
161- vacant. insert ( obligation. clone ( ) . into_owned ( ) , ( ) ) ;
162- }
146+ let mut seen = FxHashMap :: with_capacity_and_hasher ( initial_size, Default :: default ( ) ) ;
147+
148+ let mut is_duplicate = move |obligation : & Obligation < ' tcx , _ > | -> bool {
149+ return match seen. raw_entry_mut ( ) . from_key ( obligation) {
150+ RawEntryMut :: Occupied ( ..) => true ,
151+ RawEntryMut :: Vacant ( vacant) => {
152+ vacant. insert ( obligation. clone ( ) , ( ) ) ;
153+ false
163154 }
164- Some ( obligation. into_owned ( ) )
165- } )
166- . collect ( ) ;
155+ } ;
156+ } ;
157+
158+ self . obligations . retain ( |obligation| !is_duplicate ( obligation) ) ;
159+ self . obligations . extend ( iter. filter_map ( |obligation| {
160+ if is_duplicate ( obligation. borrow ( ) ) {
161+ return None ;
162+ }
163+ Some ( obligation. into_owned ( ) )
164+ } ) ) ;
167165 }
168166 }
169167}
0 commit comments