Skip to content

Commit dfaf4a0

Browse files
zhuyunxingLambdaris
zhuyunxing
authored andcommitted
coverage. Trace Candidate and MatchPair with coverage id
1 parent 3531e90 commit dfaf4a0

File tree

3 files changed

+118
-0
lines changed

3 files changed

+118
-0
lines changed

compiler/rustc_middle/src/mir/coverage.rs

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

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

+1
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ impl<'tcx> MatchPairTree<'tcx> {
263263
subpairs,
264264
pattern_ty: pattern.ty,
265265
pattern_span: pattern.span,
266+
coverage_id: Default::default(),
266267
}
267268
}
268269
}

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

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

10991103
impl<'tcx> Candidate<'tcx> {
@@ -1122,6 +1126,7 @@ impl<'tcx> Candidate<'tcx> {
11221126
otherwise_block: None,
11231127
pre_binding_block: None,
11241128
false_edge_start_block: None,
1129+
coverage_id: coverage::CandidateCovId::default(),
11251130
}
11261131
}
11271132

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

11571187
/// A depth-first traversal of the `Candidate` and all of its recursive
@@ -1276,6 +1306,9 @@ pub(crate) struct MatchPairTree<'tcx> {
12761306
pattern_ty: Ty<'tcx>,
12771307
/// Span field of the pattern this node was created from.
12781308
pattern_span: Span,
1309+
1310+
/// Key to identify the match pair in coverage.
1311+
coverage_id: coverage::MatchPairId,
12791312
}
12801313

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

0 commit comments

Comments
 (0)