@@ -24,8 +24,18 @@ pub enum VtblSegment<'tcx> {
2424pub fn prepare_vtable_segments < ' tcx , T > (
2525 tcx : TyCtxt < ' tcx > ,
2626 trait_ref : ty:: PolyTraitRef < ' tcx > ,
27- mut segment_visitor : impl FnMut ( VtblSegment < ' tcx > ) -> ControlFlow < T > ,
27+ segment_visitor : impl FnMut ( VtblSegment < ' tcx > ) -> ControlFlow < T > ,
2828) -> Option < T > {
29+ prepare_vtable_segments_inner ( tcx, trait_ref, segment_visitor) . break_value ( )
30+ }
31+
32+ /// Helper for [`prepare_vtable_segments`] that returns `ControlFlow`,
33+ /// such that we can use `?` in the body.
34+ fn prepare_vtable_segments_inner < ' tcx , T > (
35+ tcx : TyCtxt < ' tcx > ,
36+ trait_ref : ty:: PolyTraitRef < ' tcx > ,
37+ mut segment_visitor : impl FnMut ( VtblSegment < ' tcx > ) -> ControlFlow < T > ,
38+ ) -> ControlFlow < T > {
2939 // The following constraints holds for the final arrangement.
3040 // 1. The whole virtual table of the first direct super trait is included as the
3141 // the prefix. If this trait doesn't have any super traits, then this step
@@ -71,9 +81,7 @@ pub fn prepare_vtable_segments<'tcx, T>(
7181 // N, N-vptr, O
7282
7383 // emit dsa segment first.
74- if let ControlFlow :: Break ( v) = ( segment_visitor) ( VtblSegment :: MetadataDSA ) {
75- return Some ( v) ;
76- }
84+ segment_visitor ( VtblSegment :: MetadataDSA ) ?;
7785
7886 let mut emit_vptr_on_new_entry = false ;
7987 let mut visited = PredicateSet :: new ( tcx) ;
@@ -146,12 +154,10 @@ pub fn prepare_vtable_segments<'tcx, T>(
146154 // emit innermost item, move to next sibling and stop there if possible, otherwise jump to outer level.
147155 ' exiting_out: loop {
148156 if let Some ( ( inner_most_trait_ref, emit_vptr, siblings_opt) ) = stack. last_mut ( ) {
149- if let ControlFlow :: Break ( v ) = ( segment_visitor) ( VtblSegment :: TraitOwnEntries {
157+ segment_visitor ( VtblSegment :: TraitOwnEntries {
150158 trait_ref : * inner_most_trait_ref,
151159 emit_vptr : * emit_vptr,
152- } ) {
153- return Some ( v) ;
154- }
160+ } ) ?;
155161
156162 ' exiting_out_skip_visited_traits: loop {
157163 if let Some ( siblings) = siblings_opt {
@@ -174,7 +180,7 @@ pub fn prepare_vtable_segments<'tcx, T>(
174180 }
175181 }
176182 // all done
177- return None ;
183+ return ControlFlow :: Continue ( ( ) ) ;
178184 }
179185 }
180186}
0 commit comments