diff options
| author | Zalathar <Zalathar@users.noreply.github.com> | 2024-04-17 11:41:40 +1000 |
|---|---|---|
| committer | Zalathar <Zalathar@users.noreply.github.com> | 2024-04-30 22:35:54 +1000 |
| commit | c9dd07dd5e7eb84ac4b1cc27fc2ee620b2a2dfd2 (patch) | |
| tree | 9fe8aeb5ab1ccc78f4d5cd2557018c7921bbda1c /compiler | |
| parent | 47314eb427e1a9fb4f347cbeb44729486b6dbf53 (diff) | |
| download | rust-c9dd07dd5e7eb84ac4b1cc27fc2ee620b2a2dfd2.tar.gz rust-c9dd07dd5e7eb84ac4b1cc27fc2ee620b2a2dfd2.zip | |
coverage: Add branch coverage support for let-else
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_mir_build/src/build/coverageinfo.rs | 26 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/matches/mod.rs | 4 |
2 files changed, 27 insertions, 3 deletions
diff --git a/compiler/rustc_mir_build/src/build/coverageinfo.rs b/compiler/rustc_mir_build/src/build/coverageinfo.rs index e2a5f97a847..2ebbb779933 100644 --- a/compiler/rustc_mir_build/src/build/coverageinfo.rs +++ b/compiler/rustc_mir_build/src/build/coverageinfo.rs @@ -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); + } } diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index bce15267759..54ffafb000b 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -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() }); |
