1 //! Metadata from source code coverage analysis and instrumentation.
3 use rustc_macros::HashStable;
4 use rustc_span::Symbol;
7 use std::fmt::{self, Debug, Formatter};
9 rustc_index::newtype_index! {
10 pub struct ExpressionOperandId {
12 DEBUG_FORMAT = "ExpressionOperandId({})",
17 impl ExpressionOperandId {
18 /// An expression operand for a "zero counter", as described in the following references:
20 /// * https://github.com/rust-lang/llvm-project/blob/llvmorg-8.0.0/llvm/docs/CoverageMappingFormat.rst#counter
21 /// * https://github.com/rust-lang/llvm-project/blob/llvmorg-8.0.0/llvm/docs/CoverageMappingFormat.rst#tag
22 /// * https://github.com/rust-lang/llvm-project/blob/llvmorg-8.0.0/llvm/docs/CoverageMappingFormat.rst#counter-expressions
24 /// This operand can be used to count two or more separate code regions with a single counter,
25 /// if they run sequentially with no branches, by injecting the `Counter` in a `BasicBlock` for
26 /// one of the code regions, and inserting `CounterExpression`s ("add ZERO to the counter") in
27 /// the coverage map for the other code regions.
28 pub const ZERO: Self = Self::from_u32(0);
31 rustc_index::newtype_index! {
32 pub struct CounterValueReference {
34 DEBUG_FORMAT = "CounterValueReference({})",
39 impl CounterValueReference {
40 // Counters start at 1 to reserve 0 for ExpressionOperandId::ZERO.
41 pub const START: Self = Self::from_u32(1);
44 rustc_index::newtype_index! {
45 pub struct InjectedExpressionIndex {
47 DEBUG_FORMAT = "InjectedExpressionIndex({})",
52 rustc_index::newtype_index! {
53 pub struct MappedExpressionIndex {
55 DEBUG_FORMAT = "MappedExpressionIndex({})",
60 impl From<CounterValueReference> for ExpressionOperandId {
62 fn from(v: CounterValueReference) -> ExpressionOperandId {
63 ExpressionOperandId::from(v.as_u32())
67 impl From<InjectedExpressionIndex> for ExpressionOperandId {
69 fn from(v: InjectedExpressionIndex) -> ExpressionOperandId {
70 ExpressionOperandId::from(v.as_u32())
74 #[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
75 pub enum CoverageKind {
77 function_source_hash: u64,
78 id: CounterValueReference,
81 id: InjectedExpressionIndex,
82 lhs: ExpressionOperandId,
84 rhs: ExpressionOperandId,
90 pub fn as_operand_id(&self) -> ExpressionOperandId {
92 CoverageKind::Counter { id, .. } => ExpressionOperandId::from(id),
93 CoverageKind::Expression { id, .. } => ExpressionOperandId::from(id),
94 CoverageKind::Unreachable => {
95 bug!("Unreachable coverage cannot be part of an expression")
101 #[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, PartialEq, Eq, PartialOrd, Ord)]
102 pub struct CodeRegion {
103 pub file_name: Symbol,
110 impl Debug for CodeRegion {
111 fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
115 self.file_name, self.start_line, self.start_col, self.end_line, self.end_col
120 #[derive(Copy, Clone, Debug, PartialEq, TyEncodable, TyDecodable, HashStable, TypeFoldable)]