Skip to content

Commit d8675de

Browse files
committed
don't rebuild Vec when dedup might just shrink it enough that resizing isn't needed
1 parent 4075f43 commit d8675de

File tree

1 file changed

+20
-22
lines changed
  • compiler/rustc_infer/src/traits

1 file changed

+20
-22
lines changed

compiler/rustc_infer/src/traits/mod.rs

+20-22
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)