coverage: Add branch coverage support for let-else
This commit is contained in:
parent
47314eb427
commit
c9dd07dd5e
4 changed files with 36 additions and 6 deletions
|
@ -1,17 +1,18 @@
|
|||
mod mcdc;
|
||||
use std::assert_matches::assert_matches;
|
||||
use std::collections::hash_map::Entry;
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_middle::mir::coverage::{BlockMarkerId, BranchSpan, CoverageKind};
|
||||
use rustc_middle::mir::{self, BasicBlock, SourceInfo, UnOp};
|
||||
use rustc_middle::thir::{ExprId, ExprKind, Thir};
|
||||
use rustc_middle::thir::{ExprId, ExprKind, Pat, Thir};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
|
||||
use crate::build::coverageinfo::mcdc::MCDCInfoBuilder;
|
||||
use crate::build::{Builder, CFG};
|
||||
|
||||
mod mcdc;
|
||||
|
||||
pub(crate) struct BranchInfoBuilder {
|
||||
/// Maps condition expressions to their enclosing `!`, for better instrumentation.
|
||||
nots: FxHashMap<ExprId, NotInfo>,
|
||||
|
@ -155,7 +156,7 @@ impl BranchInfoBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
impl Builder<'_, '_> {
|
||||
impl<'tcx> Builder<'_, 'tcx> {
|
||||
/// If branch coverage is enabled, inject marker statements into `then_block`
|
||||
/// and `else_block`, and record their IDs in the table of branch spans.
|
||||
pub(crate) fn visit_coverage_branch_condition(
|
||||
|
@ -195,4 +196,23 @@ impl Builder<'_, '_> {
|
|||
|
||||
branch_info.add_two_way_branch(&mut self.cfg, source_info, then_block, else_block);
|
||||
}
|
||||
|
||||
/// If branch coverage is enabled, inject marker statements into `true_block`
|
||||
/// and `false_block`, and record their IDs in the table of branches.
|
||||
///
|
||||
/// Used to instrument let-else for branch coverage.
|
||||
pub(crate) fn visit_coverage_conditional_let(
|
||||
&mut self,
|
||||
pattern: &Pat<'tcx>, // Pattern that has been matched when the true path is taken
|
||||
true_block: BasicBlock,
|
||||
false_block: BasicBlock,
|
||||
) {
|
||||
// Bail out if branch coverage is not enabled for this function.
|
||||
let Some(branch_info) = self.coverage_branch_info.as_mut() else { return };
|
||||
|
||||
// FIXME(#124144) This may need special handling when MC/DC is enabled.
|
||||
|
||||
let source_info = SourceInfo { span: pattern.span, scope: self.source_scope };
|
||||
branch_info.add_two_way_branch(&mut self.cfg, source_info, true_block, false_block);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2452,6 +2452,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
None,
|
||||
true,
|
||||
);
|
||||
|
||||
// If branch coverage is enabled, record this branch.
|
||||
this.visit_coverage_conditional_let(pattern, matching, failure);
|
||||
|
||||
this.break_for_else(failure, this.source_info(initializer_span));
|
||||
matching.unit()
|
||||
});
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
Function name: let_else::let_else
|
||||
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]
|
||||
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]
|
||||
Number of files: 1
|
||||
- file 0 => global file 1
|
||||
Number of expressions: 2
|
||||
- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
|
||||
- expression 1 operands: lhs = Counter(2), rhs = Expression(0, Sub)
|
||||
Number of file 0 mappings: 6
|
||||
Number of file 0 mappings: 7
|
||||
- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 16)
|
||||
- Code(Expression(0, Sub)) at (prev + 3, 14) to (start + 0, 15)
|
||||
- Branch { true: Expression(0, Sub), false: Counter(2) } at (prev + 3, 9) to (start + 0, 16)
|
||||
true = (c1 - c2)
|
||||
false = c2
|
||||
- Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 15)
|
||||
= (c1 - c2)
|
||||
- Code(Counter(1)) at (prev + 0, 19) to (start + 0, 24)
|
||||
- Code(Counter(2)) at (prev + 1, 9) to (start + 1, 15)
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
LL| |
|
||||
LL| 3| let Some(x) = value else {
|
||||
^2
|
||||
------------------
|
||||
| Branch (LL:9): [True: 2, False: 1]
|
||||
------------------
|
||||
LL| 1| say("none");
|
||||
LL| 1| return;
|
||||
LL| | };
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue