@@ -4,7 +4,8 @@ use std::collections::VecDeque;
44
55use rustc_data_structures:: fx:: FxHashMap ;
66use rustc_middle:: mir:: coverage:: {
7- BlockMarkerId , BranchSpan , ConditionId , ConditionInfo , CoverageKind , DecisionSpan ,
7+ BlockMarkerId , BranchSpan , ConditionId , ConditionInfo , CoverageKind , MCDCBranchSpan ,
8+ MCDCDecisionSpan ,
89} ;
910use rustc_middle:: mir:: { self , BasicBlock , UnOp } ;
1011use rustc_middle:: thir:: { ExprId , ExprKind , LogicalOp , Thir } ;
@@ -21,7 +22,8 @@ pub(crate) struct BranchInfoBuilder {
2122
2223 num_block_markers : usize ,
2324 branch_spans : Vec < BranchSpan > ,
24- decision_spans : Vec < DecisionSpan > ,
25+ mcdc_branch_spans : Vec < MCDCBranchSpan > ,
26+ mcdc_decision_spans : Vec < MCDCDecisionSpan > ,
2527 mcdc_state : Option < MCDCState > ,
2628}
2729
@@ -44,7 +46,8 @@ impl BranchInfoBuilder {
4446 nots : FxHashMap :: default ( ) ,
4547 num_block_markers : 0 ,
4648 branch_spans : vec ! [ ] ,
47- decision_spans : vec ! [ ] ,
49+ mcdc_branch_spans : vec ! [ ] ,
50+ mcdc_decision_spans : vec ! [ ] ,
4851 mcdc_state : MCDCState :: new_if_enabled ( tcx) ,
4952 } )
5053 } else {
@@ -103,10 +106,8 @@ impl BranchInfoBuilder {
103106 tcx : TyCtxt < ' _ > ,
104107 true_marker : BlockMarkerId ,
105108 false_marker : BlockMarkerId ,
106- ) -> ConditionInfo {
107- let Some ( mcdc_state) = self . mcdc_state . as_mut ( ) else {
108- return ConditionInfo :: default ( ) ;
109- } ;
109+ ) -> Option < ConditionInfo > {
110+ let mcdc_state = self . mcdc_state . as_mut ( ) ?;
110111 let ( mut condition_info, decision_result) =
111112 mcdc_state. take_condition ( true_marker, false_marker) ;
112113 if let Some ( decision) = decision_result {
@@ -115,17 +116,22 @@ impl BranchInfoBuilder {
115116 unreachable ! ( "Decision with no condition is not expected" ) ;
116117 }
117118 1 ..=MAX_CONDITIONS_NUM_IN_DECISION => {
118- self . decision_spans . push ( decision) ;
119+ self . mcdc_decision_spans . push ( decision) ;
119120 }
120121 _ => {
121122 // Do not generate mcdc mappings and statements for decisions with too many conditions.
122- for branch in
123- self . branch_spans . iter_mut ( ) . rev ( ) . take ( decision. conditions_num - 1 )
124- {
125- branch. condition_info = ConditionInfo :: default ( ) ;
126- }
123+ let rebase_idx = self . mcdc_branch_spans . len ( ) - decision. conditions_num + 1 ;
124+ let to_normal_branches = self . mcdc_branch_spans . split_off ( rebase_idx) ;
125+ self . branch_spans . extend ( to_normal_branches. into_iter ( ) . map (
126+ |MCDCBranchSpan { span, true_marker, false_marker, .. } | BranchSpan {
127+ span,
128+ true_marker,
129+ false_marker,
130+ } ,
131+ ) ) ;
132+
127133 // ConditionInfo of this branch shall also be reset.
128- condition_info = ConditionInfo :: default ( ) ;
134+ condition_info = None ;
129135
130136 tcx. dcx ( ) . emit_warn ( MCDCExceedsConditionNumLimit {
131137 span : decision. span ,
@@ -145,7 +151,14 @@ impl BranchInfoBuilder {
145151 }
146152
147153 pub ( crate ) fn into_done ( self ) -> Option < Box < mir:: coverage:: BranchInfo > > {
148- let Self { nots : _, num_block_markers, branch_spans, decision_spans, .. } = self ;
154+ let Self {
155+ nots : _,
156+ num_block_markers,
157+ branch_spans,
158+ mcdc_branch_spans,
159+ mcdc_decision_spans,
160+ ..
161+ } = self ;
149162
150163 if num_block_markers == 0 {
151164 assert ! ( branch_spans. is_empty( ) ) ;
@@ -155,7 +168,8 @@ impl BranchInfoBuilder {
155168 Some ( Box :: new ( mir:: coverage:: BranchInfo {
156169 num_block_markers,
157170 branch_spans,
158- decision_spans,
171+ mcdc_branch_spans,
172+ mcdc_decision_spans,
159173 } ) )
160174 }
161175}
@@ -168,7 +182,7 @@ const MAX_CONDITIONS_NUM_IN_DECISION: usize = 6;
168182struct MCDCState {
169183 /// To construct condition evaluation tree.
170184 decision_stack : VecDeque < ConditionInfo > ,
171- processing_decision : Option < DecisionSpan > ,
185+ processing_decision : Option < MCDCDecisionSpan > ,
172186}
173187
174188impl MCDCState {
@@ -224,10 +238,10 @@ impl MCDCState {
224238 decision. span = decision. span . to ( span) ;
225239 decision
226240 }
227- None => self . processing_decision . insert ( DecisionSpan {
241+ None => self . processing_decision . insert ( MCDCDecisionSpan {
228242 span,
229243 conditions_num : 0 ,
230- end_marker : vec ! [ ] ,
244+ end_markers : vec ! [ ] ,
231245 } ) ,
232246 } ;
233247
@@ -279,24 +293,24 @@ impl MCDCState {
279293 & mut self ,
280294 true_marker : BlockMarkerId ,
281295 false_marker : BlockMarkerId ,
282- ) -> ( ConditionInfo , Option < DecisionSpan > ) {
296+ ) -> ( Option < ConditionInfo > , Option < MCDCDecisionSpan > ) {
283297 let Some ( condition_info) = self . decision_stack . pop_back ( ) else {
284- return ( ConditionInfo :: default ( ) , None ) ;
298+ return ( None , None ) ;
285299 } ;
286300 let Some ( decision) = self . processing_decision . as_mut ( ) else {
287301 bug ! ( "Processing decision should have been created before any conditions are taken" ) ;
288302 } ;
289303 if condition_info. true_next_id == ConditionId :: NONE {
290- decision. end_marker . push ( true_marker) ;
304+ decision. end_markers . push ( true_marker) ;
291305 }
292306 if condition_info. false_next_id == ConditionId :: NONE {
293- decision. end_marker . push ( false_marker) ;
307+ decision. end_markers . push ( false_marker) ;
294308 }
295309
296310 if self . decision_stack . is_empty ( ) {
297- ( condition_info, self . processing_decision . take ( ) )
311+ ( Some ( condition_info) , self . processing_decision . take ( ) )
298312 } else {
299- ( condition_info, None )
313+ ( Some ( condition_info) , None )
300314 }
301315 }
302316}
@@ -341,14 +355,22 @@ impl Builder<'_, '_> {
341355 let true_marker = inject_branch_marker ( then_block) ;
342356 let false_marker = inject_branch_marker ( else_block) ;
343357
344- let condition_info = branch_info. fetch_condition_info ( self . tcx , true_marker, false_marker) ;
345-
346- branch_info. branch_spans . push ( BranchSpan {
347- span : source_info. span ,
348- condition_info,
349- true_marker,
350- false_marker,
351- } ) ;
358+ if let Some ( condition_info) =
359+ branch_info. fetch_condition_info ( self . tcx , true_marker, false_marker)
360+ {
361+ branch_info. mcdc_branch_spans . push ( MCDCBranchSpan {
362+ span : source_info. span ,
363+ condition_info,
364+ true_marker,
365+ false_marker,
366+ } ) ;
367+ } else {
368+ branch_info. branch_spans . push ( BranchSpan {
369+ span : source_info. span ,
370+ true_marker,
371+ false_marker,
372+ } ) ;
373+ }
352374 }
353375
354376 pub ( crate ) fn visit_coverage_branch_operation ( & mut self , logical_op : LogicalOp , span : Span ) {
0 commit comments