@@ -24,8 +24,18 @@ pub enum VtblSegment<'tcx> {
24
24
pub fn prepare_vtable_segments < ' tcx , T > (
25
25
tcx : TyCtxt < ' tcx > ,
26
26
trait_ref : ty:: PolyTraitRef < ' tcx > ,
27
- mut segment_visitor : impl FnMut ( VtblSegment < ' tcx > ) -> ControlFlow < T > ,
27
+ segment_visitor : impl FnMut ( VtblSegment < ' tcx > ) -> ControlFlow < T > ,
28
28
) -> 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 > {
29
39
// The following constraints holds for the final arrangement.
30
40
// 1. The whole virtual table of the first direct super trait is included as the
31
41
// 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>(
71
81
// N, N-vptr, O
72
82
73
83
// emit dsa segment first.
74
- if let ControlFlow :: Break ( v) = ( segment_visitor) ( VtblSegment :: MetadataDSA ) {
75
- return Some ( v) ;
76
- }
84
+ segment_visitor ( VtblSegment :: MetadataDSA ) ?;
77
85
78
86
let mut emit_vptr_on_new_entry = false ;
79
87
let mut visited = PredicateSet :: new ( tcx) ;
@@ -146,12 +154,10 @@ pub fn prepare_vtable_segments<'tcx, T>(
146
154
// emit innermost item, move to next sibling and stop there if possible, otherwise jump to outer level.
147
155
' exiting_out: loop {
148
156
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 {
150
158
trait_ref : * inner_most_trait_ref,
151
159
emit_vptr : * emit_vptr,
152
- } ) {
153
- return Some ( v) ;
154
- }
160
+ } ) ?;
155
161
156
162
' exiting_out_skip_visited_traits: loop {
157
163
if let Some ( siblings) = siblings_opt {
@@ -174,7 +180,7 @@ pub fn prepare_vtable_segments<'tcx, T>(
174
180
}
175
181
}
176
182
// all done
177
- return None ;
183
+ return ControlFlow :: Continue ( ( ) ) ;
178
184
}
179
185
}
180
186
}
0 commit comments