Skip to content

Added some unit tests as requested #78963

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 15, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -721,6 +721,13 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a21fa21941700a3cd8fcb4091f361a6a712fac632f85d9f487cc892045d55c6"

[[package]]
name = "coverage_test_macros"
version = "0.0.0"
dependencies = [
"proc-macro2",
]

[[package]]
name = "cpuid-bool"
version = "0.1.2"
@@ -3922,6 +3929,7 @@ dependencies = [
name = "rustc_mir"
version = "0.0.0"
dependencies = [
"coverage_test_macros",
"either",
"itertools 0.9.0",
"polonius-engine",
12 changes: 12 additions & 0 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
@@ -611,6 +611,18 @@ pub struct TyS<'tcx> {
outer_exclusive_binder: ty::DebruijnIndex,
}

impl<'tcx> TyS<'tcx> {
/// A constructor used only for internal testing.
#[allow(rustc::usage_of_ty_tykind)]
pub fn make_for_test(
kind: TyKind<'tcx>,
flags: TypeFlags,
outer_exclusive_binder: ty::DebruijnIndex,
) -> TyS<'tcx> {
TyS { kind, flags, outer_exclusive_binder }
}
}

// `TyS` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
static_assert_size!(TyS<'_>, 32);
3 changes: 3 additions & 0 deletions compiler/rustc_mir/Cargo.toml
Original file line number Diff line number Diff line change
@@ -31,3 +31,6 @@ rustc_ast = { path = "../rustc_ast" }
rustc_span = { path = "../rustc_span" }
rustc_apfloat = { path = "../rustc_apfloat" }
smallvec = { version = "1.0", features = ["union", "may_dangle"] }

[dev-dependencies]
coverage_test_macros = { path = "src/transform/coverage/test_macros" }
5 changes: 2 additions & 3 deletions compiler/rustc_mir/src/transform/coverage/counters.rs
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ use rustc_middle::mir::coverage::*;

/// Manages the counter and expression indexes/IDs to generate `CoverageKind` components for MIR
/// `Coverage` statements.
pub(crate) struct CoverageCounters {
pub(super) struct CoverageCounters {
function_source_hash: u64,
next_counter_id: u32,
num_expressions: u32,
@@ -37,7 +37,7 @@ impl CoverageCounters {
self.debug_counters.enable();
}

/// Makes `CoverageKind` `Counter`s and `Expressions` for the `BasicCoverageBlocks` directly or
/// Makes `CoverageKind` `Counter`s and `Expressions` for the `BasicCoverageBlock`s directly or
/// indirectly associated with `CoverageSpans`, and returns additional `Expression`s
/// representing intermediate values.
pub fn make_bcb_counters(
@@ -120,7 +120,6 @@ struct BcbCounters<'a> {
basic_coverage_blocks: &'a mut CoverageGraph,
}

// FIXME(richkadel): Add unit tests for `BcbCounters` functions/algorithms.
impl<'a> BcbCounters<'a> {
fn new(
coverage_counters: &'a mut CoverageCounters,
16 changes: 8 additions & 8 deletions compiler/rustc_mir/src/transform/coverage/debug.rs
Original file line number Diff line number Diff line change
@@ -127,7 +127,7 @@ pub const NESTED_INDENT: &str = " ";

const RUSTC_COVERAGE_DEBUG_OPTIONS: &str = "RUSTC_COVERAGE_DEBUG_OPTIONS";

pub(crate) fn debug_options<'a>() -> &'a DebugOptions {
pub(super) fn debug_options<'a>() -> &'a DebugOptions {
static DEBUG_OPTIONS: SyncOnceCell<DebugOptions> = SyncOnceCell::new();

&DEBUG_OPTIONS.get_or_init(|| DebugOptions::from_env())
@@ -136,7 +136,7 @@ pub(crate) fn debug_options<'a>() -> &'a DebugOptions {
/// Parses and maintains coverage-specific debug options captured from the environment variable
/// "RUSTC_COVERAGE_DEBUG_OPTIONS", if set.
#[derive(Debug, Clone)]
pub(crate) struct DebugOptions {
pub(super) struct DebugOptions {
pub allow_unused_expressions: bool,
counter_format: ExpressionFormat,
}
@@ -250,7 +250,7 @@ impl Default for ExpressionFormat {
///
/// `DebugCounters` supports a recursive rendering of `Expression` counters, so they can be
/// presented as nested expressions such as `(bcb3 - (bcb0 + bcb1))`.
pub(crate) struct DebugCounters {
pub(super) struct DebugCounters {
some_counters: Option<FxHashMap<ExpressionOperandId, DebugCounter>>,
}

@@ -386,7 +386,7 @@ impl DebugCounter {

/// If enabled, this data structure captures additional debugging information used when generating
/// a Graphviz (.dot file) representation of the `CoverageGraph`, for debugging purposes.
pub(crate) struct GraphvizData {
pub(super) struct GraphvizData {
some_bcb_to_coverage_spans_with_counters:
Option<FxHashMap<BasicCoverageBlock, Vec<(CoverageSpan, CoverageKind)>>>,
some_bcb_to_dependency_counters: Option<FxHashMap<BasicCoverageBlock, Vec<CoverageKind>>>,
@@ -496,7 +496,7 @@ impl GraphvizData {
/// directly or indirectly, to compute the coverage counts for all `CoverageSpan`s, and any that are
/// _not_ used are retained in the `unused_expressions` Vec, to be included in debug output (logs
/// and/or a `CoverageGraph` graphviz output).
pub(crate) struct UsedExpressions {
pub(super) struct UsedExpressions {
some_used_expression_operands:
Option<FxHashMap<ExpressionOperandId, Vec<InjectedExpressionId>>>,
some_unused_expressions:
@@ -626,7 +626,7 @@ impl UsedExpressions {
}

/// Generates the MIR pass `CoverageSpan`-specific spanview dump file.
pub(crate) fn dump_coverage_spanview(
pub(super) fn dump_coverage_spanview(
tcx: TyCtxt<'tcx>,
mir_body: &mir::Body<'tcx>,
basic_coverage_blocks: &CoverageGraph,
@@ -666,7 +666,7 @@ fn span_viewables(
}

/// Generates the MIR pass coverage-specific graphviz dump file.
pub(crate) fn dump_coverage_graphviz(
pub(super) fn dump_coverage_graphviz(
tcx: TyCtxt<'tcx>,
mir_body: &mir::Body<'tcx>,
pass_name: &str,
@@ -815,7 +815,7 @@ fn bcb_to_string_sections(

/// Returns a simple string representation of a `TerminatorKind` variant, indenpendent of any
/// values it might hold.
pub(crate) fn term_type(kind: &TerminatorKind<'tcx>) -> &'static str {
pub(super) fn term_type(kind: &TerminatorKind<'tcx>) -> &'static str {
match kind {
TerminatorKind::Goto { .. } => "Goto",
TerminatorKind::SwitchInt { .. } => "SwitchInt",
16 changes: 8 additions & 8 deletions compiler/rustc_mir/src/transform/coverage/graph.rs
Original file line number Diff line number Diff line change
@@ -17,7 +17,8 @@ const ID_SEPARATOR: &str = ",";
/// `CoverageKind` counter (to be added by `CoverageCounters::make_bcb_counters`), and an optional
/// set of additional counters--if needed--to count incoming edges, if there are more than one.
/// (These "edge counters" are eventually converted into new MIR `BasicBlock`s.)
pub(crate) struct CoverageGraph {
#[derive(Debug)]
pub(super) struct CoverageGraph {
bcbs: IndexVec<BasicCoverageBlock, BasicCoverageBlockData>,
bb_to_bcb: IndexVec<BasicBlock, Option<BasicCoverageBlock>>,
pub successors: IndexVec<BasicCoverageBlock, Vec<BasicCoverageBlock>>,
@@ -275,7 +276,7 @@ impl graph::WithPredecessors for CoverageGraph {

rustc_index::newtype_index! {
/// A node in the [control-flow graph][CFG] of CoverageGraph.
pub(crate) struct BasicCoverageBlock {
pub(super) struct BasicCoverageBlock {
DEBUG_FORMAT = "bcb{}",
}
}
@@ -305,7 +306,7 @@ rustc_index::newtype_index! {
/// queries (`is_dominated_by()`, `predecessors`, `successors`, etc.) have branch (control flow)
/// significance.
#[derive(Debug, Clone)]
pub(crate) struct BasicCoverageBlockData {
pub(super) struct BasicCoverageBlockData {
pub basic_blocks: Vec<BasicBlock>,
pub counter_kind: Option<CoverageKind>,
edge_from_bcbs: Option<FxHashMap<BasicCoverageBlock, CoverageKind>>,
@@ -431,7 +432,7 @@ impl BasicCoverageBlockData {
/// the specific branching BCB, representing the edge between the two. The latter case
/// distinguishes this incoming edge from other incoming edges to the same `target_bcb`.
#[derive(Clone, Copy, PartialEq, Eq)]
pub(crate) struct BcbBranch {
pub(super) struct BcbBranch {
pub edge_from_bcb: Option<BasicCoverageBlock>,
pub target_bcb: BasicCoverageBlock,
}
@@ -498,9 +499,8 @@ fn bcb_filtered_successors<'a, 'tcx>(
/// Maintains separate worklists for each loop in the BasicCoverageBlock CFG, plus one for the
/// CoverageGraph outside all loops. This supports traversing the BCB CFG in a way that
/// ensures a loop is completely traversed before processing Blocks after the end of the loop.
// FIXME(richkadel): Add unit tests for TraversalContext.
#[derive(Debug)]
pub(crate) struct TraversalContext {
pub(super) struct TraversalContext {
/// From one or more backedges returning to a loop header.
pub loop_backedges: Option<(Vec<BasicCoverageBlock>, BasicCoverageBlock)>,

@@ -510,7 +510,7 @@ pub(crate) struct TraversalContext {
pub worklist: Vec<BasicCoverageBlock>,
}

pub(crate) struct TraverseCoverageGraphWithLoops {
pub(super) struct TraverseCoverageGraphWithLoops {
pub backedges: IndexVec<BasicCoverageBlock, Vec<BasicCoverageBlock>>,
pub context_stack: Vec<TraversalContext>,
visited: BitSet<BasicCoverageBlock>,
@@ -642,7 +642,7 @@ impl TraverseCoverageGraphWithLoops {
}
}

fn find_loop_backedges(
pub(super) fn find_loop_backedges(
basic_coverage_blocks: &CoverageGraph,
) -> IndexVec<BasicCoverageBlock, Vec<BasicCoverageBlock>> {
let num_bcbs = basic_coverage_blocks.num_nodes();
5 changes: 4 additions & 1 deletion compiler/rustc_mir/src/transform/coverage/mod.rs
Original file line number Diff line number Diff line change
@@ -5,6 +5,9 @@ mod debug;
mod graph;
mod spans;

#[cfg(test)]
mod tests;

use counters::CoverageCounters;
use graph::{BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph};
use spans::{CoverageSpan, CoverageSpans};
@@ -31,7 +34,7 @@ use rustc_span::{CharPos, Pos, SourceFile, Span, Symbol};

/// A simple error message wrapper for `coverage::Error`s.
#[derive(Debug)]
pub(crate) struct Error {
struct Error {
message: String,
}

16 changes: 11 additions & 5 deletions compiler/rustc_mir/src/transform/coverage/spans.rs
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ use rustc_span::{BytePos, Span, SyntaxContext};
use std::cmp::Ordering;

#[derive(Debug, Copy, Clone)]
pub(crate) enum CoverageStatement {
pub(super) enum CoverageStatement {
Statement(BasicBlock, Span, usize),
Terminator(BasicBlock, Span),
}
@@ -66,7 +66,7 @@ impl CoverageStatement {
/// or is subsumed by the `Span` associated with this `CoverageSpan`, and it's `BasicBlock`
/// `is_dominated_by()` the `BasicBlock`s in this `CoverageSpan`.
#[derive(Debug, Clone)]
pub(crate) struct CoverageSpan {
pub(super) struct CoverageSpan {
pub span: Span,
pub bcb: BasicCoverageBlock,
pub coverage_statements: Vec<CoverageStatement>,
@@ -214,7 +214,7 @@ pub struct CoverageSpans<'a, 'tcx> {
}

impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
pub(crate) fn generate_coverage_spans(
pub(super) fn generate_coverage_spans(
mir_body: &'a mir::Body<'tcx>,
body_span: Span,
basic_coverage_blocks: &'a CoverageGraph,
@@ -645,7 +645,10 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
}
}

fn filtered_statement_span(statement: &'a Statement<'tcx>, body_span: Span) -> Option<Span> {
pub(super) fn filtered_statement_span(
statement: &'a Statement<'tcx>,
body_span: Span,
) -> Option<Span> {
match statement.kind {
// These statements have spans that are often outside the scope of the executed source code
// for their parent `BasicBlock`.
@@ -686,7 +689,10 @@ fn filtered_statement_span(statement: &'a Statement<'tcx>, body_span: Span) -> O
}
}

fn filtered_terminator_span(terminator: &'a Terminator<'tcx>, body_span: Span) -> Option<Span> {
pub(super) fn filtered_terminator_span(
terminator: &'a Terminator<'tcx>,
body_span: Span,
) -> Option<Span> {
match terminator.kind {
// These terminators have spans that don't positively contribute to computing a reasonable
// span of actually executed source code. (For example, SwitchInt terminators extracted from
12 changes: 12 additions & 0 deletions compiler/rustc_mir/src/transform/coverage/test_macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
authors = ["The Rust Project Developers"]
name = "coverage_test_macros"
version = "0.0.0"
edition = "2018"

[lib]
proc-macro = true
doctest = false

[dependencies]
proc-macro2 = "1"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use proc_macro::TokenStream;

#[proc_macro]
pub fn let_bcb(item: TokenStream) -> TokenStream {
format!("let bcb{} = graph::BasicCoverageBlock::from_usize({});", item, item).parse().unwrap()
}
714 changes: 714 additions & 0 deletions compiler/rustc_mir/src/transform/coverage/tests.rs

Large diffs are not rendered by default.