@@ -133,37 +133,35 @@ where
133
133
}
134
134
135
135
let initial_size = self . obligations . len ( ) ;
136
- let iter = iter . into_iter ( ) ;
136
+ let current_capacity = self . obligations . capacity ( ) ;
137
137
let expected_new = iter. len ( ) ;
138
138
let combined_size = initial_size + expected_new;
139
139
140
- if combined_size <= 16 || combined_size < initial_size . next_power_of_two ( ) {
140
+ if combined_size <= 16 || combined_size <= current_capacity {
141
141
// small case/not crossing a power of two. don't bother with dedup
142
142
self . obligations . extend ( iter. map ( Cow :: into_owned) ) ;
143
143
} else {
144
144
// crossing power of two threshold. this would incur a vec growth anyway if we didn't do
145
145
// 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
163
154
}
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
+ } ) ) ;
167
165
}
168
166
}
169
167
}
0 commit comments