@@ -7,13 +7,13 @@ use rustc_middle::mir::coverage::{
77 BlockMarkerId, BranchSpan, ConditionId, ConditionInfo, CoverageKind, MCDCBranchSpan,
88 MCDCDecisionSpan,
99};
10- use rustc_middle::mir::{self, BasicBlock, UnOp};
10+ use rustc_middle::mir::{self, BasicBlock, SourceInfo, UnOp};
1111use rustc_middle::thir::{ExprId, ExprKind, LogicalOp, Thir};
1212use rustc_middle::ty::TyCtxt;
1313use rustc_span::def_id::LocalDefId;
1414use rustc_span::Span;
1515
16- use crate::build::Builder;
16+ use crate::build::{ Builder, CFG} ;
1717use crate::errors::MCDCExceedsConditionNumLimit;
1818
1919pub(crate) struct BranchInfoBuilder {
@@ -134,12 +134,42 @@ impl BranchInfoBuilder {
134134 condition_info
135135 }
136136
137+ fn add_two_way_branch<'tcx>(
138+ &mut self,
139+ cfg: &mut CFG<'tcx>,
140+ source_info: SourceInfo,
141+ true_block: BasicBlock,
142+ false_block: BasicBlock,
143+ ) {
144+ let true_marker = self.inject_block_marker(cfg, source_info, true_block);
145+ let false_marker = self.inject_block_marker(cfg, source_info, false_block);
146+
147+ self.branch_spans.push(BranchSpan { span: source_info.span, true_marker, false_marker });
148+ }
149+
137150 fn next_block_marker_id(&mut self) -> BlockMarkerId {
138151 let id = BlockMarkerId::from_usize(self.num_block_markers);
139152 self.num_block_markers += 1;
140153 id
141154 }
142155
156+ fn inject_block_marker(
157+ &mut self,
158+ cfg: &mut CFG<'_>,
159+ source_info: SourceInfo,
160+ block: BasicBlock,
161+ ) -> BlockMarkerId {
162+ let id = self.next_block_marker_id();
163+
164+ let marker_statement = mir::Statement {
165+ source_info,
166+ kind: mir::StatementKind::Coverage(CoverageKind::BlockMarker { id }),
167+ };
168+ cfg.push(block, marker_statement);
169+
170+ id
171+ }
172+
143173 pub(crate) fn into_done(self) -> Option<Box<mir::coverage::BranchInfo>> {
144174 let Self {
145175 nots: _,
@@ -315,7 +345,7 @@ impl Builder<'_, '_> {
315345 mut else_block: BasicBlock,
316346 ) {
317347 // Bail out if branch coverage is not enabled for this function.
318- let Some(branch_info) = self.coverage_branch_info.as_ref () else { return };
348+ let Some(branch_info) = self.coverage_branch_info.as_mut () else { return };
319349
320350 // If this condition expression is nested within one or more `!` expressions,
321351 // replace it with the enclosing `!` collected by `visit_unary_not`.
@@ -325,27 +355,15 @@ impl Builder<'_, '_> {
325355 std::mem::swap(&mut then_block, &mut else_block);
326356 }
327357 }
328- let source_info = self.source_info(self.thir[expr_id].span);
329-
330- // Now that we have `source_info`, we can upgrade to a &mut reference.
331- let branch_info = self.coverage_branch_info.as_mut().expect("upgrading & to &mut");
332-
333- let mut inject_branch_marker = |block: BasicBlock| {
334- let id = branch_info.next_block_marker_id();
335-
336- let marker_statement = mir::Statement {
337- source_info,
338- kind: mir::StatementKind::Coverage(CoverageKind::BlockMarker { id }),
339- };
340- self.cfg.push(block, marker_statement);
341-
342- id
343- };
344358
345- let true_marker = inject_branch_marker(then_block);
346- let false_marker = inject_branch_marker(else_block);
359+ let source_info = SourceInfo { span: self.thir[expr_id].span, scope: self.source_scope };
347360
361+ // Separate path for handling branches when MC/DC is enabled.
348362 if branch_info.mcdc_state.is_some() {
363+ let mut inject_block_marker =
364+ |block| branch_info.inject_block_marker(&mut self.cfg, source_info, block);
365+ let true_marker = inject_block_marker(then_block);
366+ let false_marker = inject_block_marker(else_block);
349367 let condition_info =
350368 branch_info.fetch_mcdc_condition_info(self.tcx, true_marker, false_marker);
351369 branch_info.mcdc_branch_spans.push(MCDCBranchSpan {
@@ -357,11 +375,7 @@ impl Builder<'_, '_> {
357375 return;
358376 }
359377
360- branch_info.branch_spans.push(BranchSpan {
361- span: source_info.span,
362- true_marker,
363- false_marker,
364- });
378+ branch_info.add_two_way_branch(&mut self.cfg, source_info, then_block, else_block);
365379 }
366380
367381 pub(crate) fn visit_coverage_branch_operation(&mut self, logical_op: LogicalOp, span: Span) {
0 commit comments