Skip to content

Commit 8bbe36f

Browse files
author
zhuyunxing
committed
coverage. Trace Candidate and MatchPair with coverage id
1 parent c98eed6 commit 8bbe36f

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
@@ -252,6 +252,6 @@ impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> {
252252
PatKind::Never => TestCase::Never,
253253
};
254254

255-
MatchPairTree { place, test_case, subpairs, pattern }
255+
MatchPairTree { place, test_case, subpairs, pattern ,coverage_id:Default::default()}
256256
}
257257
}

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

+34
Original file line numberDiff line numberDiff line change
@@ -1095,6 +1095,10 @@ struct Candidate<'pat, 'tcx> {
10951095
/// The earliest block that has only candidates >= this one as descendents. Used for false
10961096
/// edges, see the doc for [`Builder::match_expr`].
10971097
false_edge_start_block: Option<BasicBlock>,
1098+
1099+
#[allow(unused)]
1100+
/// The id to identify the candidate in coverage instrument.
1101+
coverage_id: coverage::CandidateCovId,
10981102
}
10991103

11001104
impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
@@ -1123,6 +1127,7 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
11231127
otherwise_block: None,
11241128
pre_binding_block: None,
11251129
false_edge_start_block: None,
1130+
coverage_id: coverage::CandidateCovId::default(),
11261131
}
11271132
}
11281133

@@ -1153,6 +1158,31 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
11531158
|_| {},
11541159
);
11551160
}
1161+
1162+
#[allow(unused)]
1163+
pub(crate) fn set_coverage_id(&mut self, coverage_id: coverage::CandidateCovId) {
1164+
self.coverage_id = coverage_id;
1165+
// Assign id for match pairs only if this candidate is the root.
1166+
if !coverage_id.subcandidate_id.is_root() {
1167+
return;
1168+
};
1169+
let mut latest_match_id = coverage::MatchPairId::START;
1170+
let mut next_match_id = || {
1171+
let id = latest_match_id;
1172+
latest_match_id = id.next_match_pair_id();
1173+
id
1174+
};
1175+
let mut match_pairs = self.match_pairs.iter_mut().collect::<Vec<_>>();
1176+
while let Some(match_pair) = match_pairs.pop() {
1177+
match_pair.coverage_id = next_match_id();
1178+
match_pairs.extend(match_pair.subpairs.iter_mut());
1179+
if let TestCase::Or { ref mut pats } = match_pair.test_case {
1180+
match_pairs.extend(
1181+
pats.iter_mut().map(|flat_pat| flat_pat.match_pairs.iter_mut()).flatten(),
1182+
);
1183+
}
1184+
}
1185+
}
11561186
}
11571187

11581188
/// A depth-first traversal of the `Candidate` and all of its recursive
@@ -1275,6 +1305,10 @@ pub(crate) struct MatchPairTree<'pat, 'tcx> {
12751305

12761306
/// The pattern this was created from.
12771307
pattern: &'pat Pat<'tcx>,
1308+
1309+
#[allow(unused)]
1310+
/// Key to identify the match pair in coverage.
1311+
coverage_id: coverage::MatchPairId,
12781312
}
12791313

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

0 commit comments

Comments
 (0)