Skip to content

Commit d567f0f

Browse files
committed
Slightly refactor 'exiting_out loop in prepare_vtable_segments
1. Hide the option as an iterator, so it's nicer to work with 2. Replace a loop with `find`
1 parent 364fc44 commit d567f0f

File tree

1 file changed

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

1 file changed

+22
-20
lines changed

compiler/rustc_trait_selection/src/traits/vtable.rs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ fn prepare_vtable_segments_inner<'tcx, T>(
8787
let mut visited = PredicateSet::new(tcx);
8888
let predicate = trait_ref.without_const().to_predicate(tcx);
8989
let mut stack: SmallVec<[(ty::PolyTraitRef<'tcx>, _, _); 5]> =
90-
smallvec![(trait_ref, emit_vptr_on_new_entry, None)];
90+
smallvec![(trait_ref, emit_vptr_on_new_entry, maybe_iter(None))];
9191
visited.insert(predicate);
9292

9393
// the main traversal loop:
@@ -138,7 +138,7 @@ fn prepare_vtable_segments_inner<'tcx, T>(
138138
stack.push((
139139
next_super_trait,
140140
emit_vptr_on_new_entry,
141-
Some(direct_super_traits_iter),
141+
maybe_iter(Some(direct_super_traits_iter)),
142142
))
143143
}
144144

@@ -152,30 +152,26 @@ fn prepare_vtable_segments_inner<'tcx, T>(
152152

153153
// emit innermost item, move to next sibling and stop there if possible, otherwise jump to outer level.
154154
'exiting_out: loop {
155-
if let Some((inner_most_trait_ref, emit_vptr, siblings_opt)) = stack.last_mut() {
155+
if let Some((inner_most_trait_ref, emit_vptr, siblings)) = stack.last_mut() {
156156
segment_visitor(VtblSegment::TraitOwnEntries {
157157
trait_ref: *inner_most_trait_ref,
158158
emit_vptr: *emit_vptr,
159159
})?;
160160

161-
'exiting_out_skip_visited_traits: loop {
162-
if let Some(siblings) = siblings_opt {
163-
if let Some(next_inner_most_trait_ref) = siblings.next() {
164-
if visited.insert(next_inner_most_trait_ref.to_predicate(tcx)) {
165-
// We're throwing away potential constness of super traits here.
166-
// FIXME: handle ~const super traits
167-
let next_inner_most_trait_ref =
168-
next_inner_most_trait_ref.map_bound(|t| t.trait_ref);
169-
*inner_most_trait_ref = next_inner_most_trait_ref;
170-
*emit_vptr = emit_vptr_on_new_entry;
171-
break 'exiting_out;
172-
} else {
173-
continue 'exiting_out_skip_visited_traits;
174-
}
175-
}
161+
match siblings.find(|&sibling| visited.insert(sibling.to_predicate(tcx))) {
162+
Some(next_inner_most_trait_ref) => {
163+
// We're throwing away potential constness of super traits here.
164+
// FIXME: handle ~const super traits
165+
let next_inner_most_trait_ref =
166+
next_inner_most_trait_ref.map_bound(|t| t.trait_ref);
167+
*inner_most_trait_ref = next_inner_most_trait_ref;
168+
*emit_vptr = emit_vptr_on_new_entry;
169+
break 'exiting_out;
170+
}
171+
None => {
172+
stack.pop();
173+
continue 'exiting_out;
176174
}
177-
stack.pop();
178-
continue 'exiting_out;
179175
}
180176
}
181177
// all done
@@ -184,6 +180,12 @@ fn prepare_vtable_segments_inner<'tcx, T>(
184180
}
185181
}
186182

183+
/// Turns option of iterator into an iterator (this is just flatten)
184+
fn maybe_iter<I: Iterator>(i: Option<I>) -> impl Iterator<Item = I::Item> {
185+
// Flatten is bad perf-vise, we could probably implement a special case here that is better
186+
i.into_iter().flatten()
187+
}
188+
187189
fn dump_vtable_entries<'tcx>(
188190
tcx: TyCtxt<'tcx>,
189191
sp: Span,

0 commit comments

Comments
 (0)