Skip to content

Commit 6972c6e

Browse files
committed
don't rebuild Vec when dedup might just shrink it enough that resizing isn't needed
1 parent c260e83 commit 6972c6e

File tree

1 file changed

+18
-18
lines changed
  • compiler/rustc_infer/src/traits

1 file changed

+18
-18
lines changed

compiler/rustc_infer/src/traits/mod.rs

+18-18
Original file line numberDiff line numberDiff line change
@@ -123,37 +123,37 @@ where
123123
}
124124

125125
let initial_size = self.obligations.len();
126+
let current_capacity = self.obligations.capacity();
126127
let iter = iter.into_iter();
127128
let expected_new = iter.len();
128129
let combined_size = initial_size + expected_new;
129130

130-
if combined_size <= 16 || combined_size < initial_size.next_power_of_two() {
131+
if combined_size <= 16 || combined_size <= current_capacity {
131132
// small case/not crossing a power of two. don't bother with dedup
132133
self.obligations.extend(iter.map(Cow::into_owned));
133134
} else {
134135
// crossing power of two threshold. this would incur a vec growth anyway if we didn't do
135136
// anything. piggyback a dedup on that
136-
let obligations = std::mem::take(self.obligations);
137-
138137
let mut seen = FxHashMap::default();
139138
seen.reserve(initial_size);
140139

141-
*self.obligations = obligations
142-
.into_iter()
143-
.map(Cow::Owned)
144-
.chain(iter)
145-
.filter_map(|obligation| {
146-
match seen.raw_entry_mut().from_key(obligation.borrow()) {
147-
RawEntryMut::Occupied(..) => {
148-
return None;
149-
}
150-
RawEntryMut::Vacant(vacant) => {
151-
vacant.insert(obligation.clone().into_owned(), ());
152-
}
140+
let mut is_duplicate = move |obligation: &Obligation<'tcx, _>| -> bool {
141+
return match seen.raw_entry_mut().from_key(obligation) {
142+
RawEntryMut::Occupied(..) => true,
143+
RawEntryMut::Vacant(vacant) => {
144+
vacant.insert(obligation.clone(), ());
145+
false
153146
}
154-
Some(obligation.into_owned())
155-
})
156-
.collect();
147+
};
148+
};
149+
150+
self.obligations.retain(|obligation| !is_duplicate(obligation));
151+
self.obligations.extend(iter.filter_map(|obligation| {
152+
if is_duplicate(obligation.borrow()) {
153+
return None;
154+
}
155+
Some(obligation.into_owned())
156+
}));
157157
}
158158
}
159159
}

0 commit comments

Comments
 (0)