about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorZalathar <Zalathar@users.noreply.github.com>2024-04-17 11:41:40 +1000
committerZalathar <Zalathar@users.noreply.github.com>2024-04-30 22:35:54 +1000
commitc9dd07dd5e7eb84ac4b1cc27fc2ee620b2a2dfd2 (patch)
tree9fe8aeb5ab1ccc78f4d5cd2557018c7921bbda1c /compiler
parent47314eb427e1a9fb4f347cbeb44729486b6dbf53 (diff)
downloadrust-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.rs26
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs4
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()
         });