Skip to content

Commit af2f730

Browse files
committed
coverage: Add branch coverage support for let-else
1 parent 7823bf0 commit af2f730

File tree

4 files changed

+34
-5
lines changed

4 files changed

+34
-5
lines changed

compiler/rustc_mir_build/src/build/coverageinfo.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_middle::mir::coverage::{
88
MCDCDecisionSpan,
99
};
1010
use rustc_middle::mir::{self, BasicBlock, SourceInfo, UnOp};
11-
use rustc_middle::thir::{ExprId, ExprKind, LogicalOp, Thir};
11+
use rustc_middle::thir::{ExprId, ExprKind, LogicalOp, Pat, Thir};
1212
use rustc_middle::ty::TyCtxt;
1313
use rustc_span::def_id::LocalDefId;
1414
use rustc_span::Span;
@@ -360,7 +360,7 @@ impl MCDCState {
360360
}
361361
}
362362

363-
impl Builder<'_, '_> {
363+
impl<'tcx> Builder<'_, 'tcx> {
364364
/// If branch coverage is enabled, inject marker statements into `then_block`
365365
/// and `else_block`, and record their IDs in the table of branch spans.
366366
pub(crate) fn visit_coverage_branch_condition(
@@ -407,6 +407,25 @@ impl Builder<'_, '_> {
407407
branch_info.add_two_way_branch(&mut self.cfg, source_info, then_block, else_block);
408408
}
409409

410+
/// If branch coverage is enabled, inject marker statements into `true_block`
411+
/// and `false_block`, and record their IDs in the table of branches.
412+
///
413+
/// Used to instrument let-else for branch coverage.
414+
pub(crate) fn visit_coverage_conditional_let(
415+
&mut self,
416+
pattern: &Pat<'tcx>, // Pattern that has been matched when the true path is taken
417+
true_block: BasicBlock,
418+
false_block: BasicBlock,
419+
) {
420+
// Bail out if branch coverage is not enabled for this function.
421+
let Some(branch_info) = self.coverage_branch_info.as_mut() else { return };
422+
423+
// FIXME(#124144) This may need special handling when MC/DC is enabled.
424+
425+
let source_info = SourceInfo { span: pattern.span, scope: self.source_scope };
426+
branch_info.add_two_way_branch(&mut self.cfg, source_info, true_block, false_block);
427+
}
428+
410429
pub(crate) fn visit_coverage_branch_operation(&mut self, logical_op: LogicalOp, span: Span) {
411430
if let Some(branch_info) = self.coverage_branch_info.as_mut()
412431
&& let Some(mcdc_state) = branch_info.mcdc_state.as_mut()

compiler/rustc_mir_build/src/build/matches/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -2452,6 +2452,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
24522452
None,
24532453
true,
24542454
);
2455+
2456+
// If branch coverage is enabled, record this branch.
2457+
this.visit_coverage_conditional_let(pattern, matching, failure);
2458+
24552459
this.break_for_else(failure, this.source_info(initializer_span));
24562460
matching.unit()
24572461
});

tests/coverage/branch/let-else.cov-map

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
Function name: let_else::let_else
2-
Raw bytes (38): 0x[01, 01, 02, 05, 09, 09, 02, 06, 01, 0c, 01, 01, 10, 02, 03, 0e, 00, 0f, 05, 00, 13, 00, 18, 09, 01, 09, 01, 0f, 02, 04, 05, 00, 0b, 07, 01, 01, 00, 02]
2+
Raw bytes (45): 0x[01, 01, 02, 05, 09, 09, 02, 07, 01, 0c, 01, 01, 10, 20, 02, 09, 03, 09, 00, 10, 02, 00, 0e, 00, 0f, 05, 00, 13, 00, 18, 09, 01, 09, 01, 0f, 02, 04, 05, 00, 0b, 07, 01, 01, 00, 02]
33
Number of files: 1
44
- file 0 => global file 1
55
Number of expressions: 2
66
- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
77
- expression 1 operands: lhs = Counter(2), rhs = Expression(0, Sub)
8-
Number of file 0 mappings: 6
8+
Number of file 0 mappings: 7
99
- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 16)
10-
- Code(Expression(0, Sub)) at (prev + 3, 14) to (start + 0, 15)
10+
- Branch { true: Expression(0, Sub), false: Counter(2) } at (prev + 3, 9) to (start + 0, 16)
11+
true = (c1 - c2)
12+
false = c2
13+
- Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 15)
1114
= (c1 - c2)
1215
- Code(Counter(1)) at (prev + 0, 19) to (start + 0, 24)
1316
- Code(Counter(2)) at (prev + 1, 9) to (start + 1, 15)

tests/coverage/branch/let-else.coverage

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
LL| |
1515
LL| 3| let Some(x) = value else {
1616
^2
17+
------------------
18+
| Branch (LL:9): [True: 2, False: 1]
19+
------------------
1720
LL| 1| say("none");
1821
LL| 1| return;
1922
LL| | };

0 commit comments

Comments
 (0)