Skip to content

Commit 00218a4

Browse files
zhuyunxingLambdaris
zhuyunxing
authored andcommitted
coverage. Trace Candidate and MatchPair with coverage id
1 parent be1b2e0 commit 00218a4

File tree

3 files changed

+125
-4
lines changed

3 files changed

+125
-4
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

+8-4
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,13 @@ impl<'tcx> MatchPairTree<'tcx> {
173173
let ascription = place.map(|source| {
174174
let span = pattern.span;
175175
let parent_id = cx.tcx.typeck_root_def_id(cx.def_id.to_def_id());
176-
let args = ty::InlineConstArgs::new(cx.tcx, ty::InlineConstArgsParts {
177-
parent_args: ty::GenericArgs::identity_for_item(cx.tcx, parent_id),
178-
ty: cx.infcx.next_ty_var(span),
179-
})
176+
let args = ty::InlineConstArgs::new(
177+
cx.tcx,
178+
ty::InlineConstArgsParts {
179+
parent_args: ty::GenericArgs::identity_for_item(cx.tcx, parent_id),
180+
ty: cx.infcx.next_ty_var(span),
181+
},
182+
)
180183
.args;
181184
let user_ty = cx.infcx.canonicalize_user_type_annotation(ty::UserType::new(
182185
ty::UserTypeKind::TypeOf(def_id, ty::UserArgs { args, user_self_ty: None }),
@@ -263,6 +266,7 @@ impl<'tcx> MatchPairTree<'tcx> {
263266
subpairs,
264267
pattern_ty: pattern.ty,
265268
pattern_span: pattern.span,
269+
coverage_id: Default::default(),
266270
}
267271
}
268272
}

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

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

11141118
impl<'tcx> Candidate<'tcx> {
@@ -1137,6 +1141,7 @@ impl<'tcx> Candidate<'tcx> {
11371141
otherwise_block: None,
11381142
pre_binding_block: None,
11391143
false_edge_start_block: None,
1144+
coverage_id: coverage::CandidateCovId::default(),
11401145
}
11411146
}
11421147

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

11721202
/// A depth-first traversal of the `Candidate` and all of its recursive
@@ -1291,6 +1321,9 @@ pub(crate) struct MatchPairTree<'tcx> {
12911321
pattern_ty: Ty<'tcx>,
12921322
/// Span field of the pattern this node was created from.
12931323
pattern_span: Span,
1324+
1325+
/// Key to identify the match pair in coverage.
1326+
coverage_id: coverage::MatchPairId,
12941327
}
12951328

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

0 commit comments

Comments
 (0)