Skip to content

Commit c79d9a0

Browse files
author
zhuyunxing
committed
coverage. Trace Candidate and MatchPair with coverage id
1 parent 0e3d0e6 commit c79d9a0

File tree

3 files changed

+120
-1
lines changed

3 files changed

+120
-1
lines changed

compiler/rustc_middle/src/mir/coverage.rs

+85
Original file line numberDiff line numberDiff line change
@@ -348,3 +348,88 @@ impl MCDCDecisionSpan {
348348
}
349349
}
350350
}
351+
352+
/// Identify subcandidates in a candidate.
353+
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
354+
pub struct SubcandidateId(usize);
355+
356+
impl SubcandidateId {
357+
pub const ROOT: SubcandidateId = SubcandidateId(0);
358+
pub fn is_root(&self) -> bool {
359+
*self == Self::ROOT
360+
}
361+
362+
pub fn next_subcandidate_id(&self) -> Self {
363+
Self(self.0 + 1)
364+
}
365+
}
366+
367+
/// Identify MatchPair in a candidate.
368+
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
369+
pub struct MatchPairId(usize);
370+
371+
impl MatchPairId {
372+
pub const INVALID: MatchPairId = MatchPairId(0);
373+
pub const START: MatchPairId = MatchPairId(1);
374+
pub fn next_match_pair_id(&self) -> Self {
375+
Self(self.0 + 1)
376+
}
377+
}
378+
379+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
380+
pub struct CandidateCovId {
381+
pub decision_id: DecisionId,
382+
pub subcandidate_id: SubcandidateId,
383+
}
384+
385+
impl Default for CandidateCovId {
386+
fn default() -> Self {
387+
Self { decision_id: DecisionId::MAX, subcandidate_id: SubcandidateId(usize::MAX) }
388+
}
389+
}
390+
391+
impl CandidateCovId {
392+
pub fn is_valid(&self) -> bool {
393+
*self != Self::default()
394+
}
395+
396+
pub fn new_match_info(
397+
&mut self,
398+
match_id: MatchPairId,
399+
span: Span,
400+
fully_matched: bool,
401+
) -> MatchCoverageInfo {
402+
let key = MatchKey {
403+
decision_id: self.decision_id,
404+
match_id,
405+
subcandidate_id: self.subcandidate_id,
406+
};
407+
MatchCoverageInfo { key, span, fully_matched }
408+
}
409+
}
410+
411+
/// Key for matched patterns.
412+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
413+
pub struct MatchKey {
414+
pub decision_id: DecisionId,
415+
pub match_id: MatchPairId,
416+
pub subcandidate_id: SubcandidateId,
417+
}
418+
419+
impl Default for MatchKey {
420+
fn default() -> Self {
421+
Self {
422+
decision_id: DecisionId::MAX,
423+
match_id: MatchPairId(0),
424+
subcandidate_id: SubcandidateId(0),
425+
}
426+
}
427+
}
428+
429+
/// Information about matched patterns.
430+
#[derive(Clone, Copy, Debug)]
431+
pub struct MatchCoverageInfo {
432+
pub key: MatchKey,
433+
pub span: Span,
434+
pub fully_matched: bool,
435+
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,6 @@ impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> {
250250
PatKind::Never => TestCase::Never,
251251
};
252252

253-
MatchPairTree { place, test_case, subpairs, pattern }
253+
MatchPairTree { place, test_case, subpairs, pattern ,coverage_id:Default::default()}
254254
}
255255
}

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

+34
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,10 @@ struct Candidate<'pat, 'tcx> {
11101110
/// The earliest block that has only candidates >= this one as descendents. Used for false
11111111
/// edges, see the doc for [`Builder::match_expr`].
11121112
false_edge_start_block: Option<BasicBlock>,
1113+
1114+
#[allow(unused)]
1115+
/// The id to identify the candidate in coverage instrument.
1116+
coverage_id: coverage::CandidateCovId,
11131117
}
11141118

11151119
impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
@@ -1138,6 +1142,7 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
11381142
otherwise_block: None,
11391143
pre_binding_block: None,
11401144
false_edge_start_block: None,
1145+
coverage_id: coverage::CandidateCovId::default(),
11411146
}
11421147
}
11431148

@@ -1168,6 +1173,31 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
11681173
|_| {},
11691174
);
11701175
}
1176+
1177+
#[allow(unused)]
1178+
pub(crate) fn set_coverage_id(&mut self, coverage_id: coverage::CandidateCovId) {
1179+
self.coverage_id = coverage_id;
1180+
// Assign id for match pairs only if this candidate is the root.
1181+
if !coverage_id.subcandidate_id.is_root() {
1182+
return;
1183+
};
1184+
let mut latest_match_id = coverage::MatchPairId::START;
1185+
let mut next_match_id = || {
1186+
let id = latest_match_id;
1187+
latest_match_id = id.next_match_pair_id();
1188+
id
1189+
};
1190+
let mut match_pairs = self.match_pairs.iter_mut().collect::<Vec<_>>();
1191+
while let Some(match_pair) = match_pairs.pop() {
1192+
match_pair.coverage_id = next_match_id();
1193+
match_pairs.extend(match_pair.subpairs.iter_mut());
1194+
if let TestCase::Or { ref mut pats } = match_pair.test_case {
1195+
match_pairs.extend(
1196+
pats.iter_mut().map(|flat_pat| flat_pat.match_pairs.iter_mut()).flatten(),
1197+
);
1198+
}
1199+
}
1200+
}
11711201
}
11721202

11731203
/// A depth-first traversal of the `Candidate` and all of its recursive
@@ -1290,6 +1320,10 @@ pub(crate) struct MatchPairTree<'pat, 'tcx> {
12901320

12911321
/// The pattern this was created from.
12921322
pattern: &'pat Pat<'tcx>,
1323+
1324+
#[allow(unused)]
1325+
/// Key to identify the match pair in coverage.
1326+
coverage_id: coverage::MatchPairId,
12931327
}
12941328

12951329
/// See [`Test`] for more.

0 commit comments

Comments
 (0)