Combination of commits

Fixes multiple issue with counters, with simplification

  Includes a change to the implicit else span in ast_lowering, so coverage
  of the implicit else no longer spans the `then` block.

  Adds coverage for unused closures and async function bodies.

  Fixes: #78542

Adding unreachable regions for known MIR missing from coverage map

Cleaned up PR commits, and removed link-dead-code requirement and tests

  Coverage no longer depends on Issue #76038 (`-C link-dead-code` is
  no longer needed or enforced, so MSVC can use the same tests as
  Linux and MacOS now)

Restrict adding unreachable regions to covered files

  Improved the code that adds coverage for uncalled functions (with MIR
  but not-codegenned) to avoid generating coverage in files not already
  included in the files with covered functions.

Resolved last known issue requiring --emit llvm-ir workaround

  Fixed bugs in how unreachable code spans were added.
This commit is contained in:
Rich Kadel 2020-11-30 23:58:08 -08:00
parent f6c9c1a576
commit def932ca86
354 changed files with 12634 additions and 20486 deletions

View file

@ -347,7 +347,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// `_ => else_block` where `else_block` is `{}` if there's `None`:
let else_pat = self.pat_wild(span);
let (else_expr, contains_else_clause) = match else_opt {
None => (self.expr_block_empty(span), false),
None => (self.expr_block_empty(span.shrink_to_hi()), false),
Some(els) => (self.lower_expr(els), true),
};
let else_arm = self.arm(else_pat, else_expr);

View file

@ -127,9 +127,6 @@ fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
return;
}
// FIXME(richkadel): Make sure probestack plays nice with `-Z instrument-coverage`
// or disable it if not, similar to above early exits.
// Flag our internal `__rust_probestack` function as the stack probe symbol.
// This is defined in the `compiler-builtins` crate for each architecture.
llvm::AddFunctionAttrStringValue(

View file

@ -3,11 +3,14 @@ use crate::coverageinfo;
use crate::llvm;
use llvm::coverageinfo::CounterMappingRegion;
use rustc_codegen_ssa::coverageinfo::map::{Counter, CounterExpression};
use rustc_codegen_ssa::coverageinfo::map::{Counter, CounterExpression, FunctionCoverage};
use rustc_codegen_ssa::traits::ConstMethods;
use rustc_data_structures::fx::FxIndexSet;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
use rustc_hir::def_id::{DefId, DefIdSet, LOCAL_CRATE};
use rustc_llvm::RustString;
use rustc_middle::mir::coverage::CodeRegion;
use rustc_middle::ty::{Instance, TyCtxt};
use rustc_span::Symbol;
use std::ffi::CString;
@ -26,14 +29,17 @@ use tracing::debug;
/// undocumented details in Clang's implementation (that may or may not be important) were also
/// replicated for Rust's Coverage Map.
pub fn finalize<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) {
let tcx = cx.tcx;
// Ensure LLVM supports Coverage Map Version 4 (encoded as a zero-based value: 3).
// If not, the LLVM Version must be less than 11.
let version = coverageinfo::mapping_version();
if version != 3 {
cx.tcx.sess.fatal("rustc option `-Z instrument-coverage` requires LLVM 11 or higher.");
tcx.sess.fatal("rustc option `-Z instrument-coverage` requires LLVM 11 or higher.");
}
let function_coverage_map = match cx.coverage_context() {
debug!("Generating coverage map for CodegenUnit: `{}`", cx.codegen_unit.name());
let mut function_coverage_map = match cx.coverage_context() {
Some(ctx) => ctx.take_function_coverage_map(),
None => return,
};
@ -42,14 +48,15 @@ pub fn finalize<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) {
return;
}
add_unreachable_coverage(tcx, &mut function_coverage_map);
let mut mapgen = CoverageMapGenerator::new();
// Encode coverage mappings and generate function records
let mut function_data = Vec::new();
for (instance, function_coverage) in function_coverage_map {
debug!("Generate coverage map for: {:?}", instance);
let mangled_function_name = cx.tcx.symbol_name(instance).to_string();
debug!("Generate function coverage for {}, {:?}", cx.codegen_unit.name(), instance);
let mangled_function_name = tcx.symbol_name(instance).to_string();
let function_source_hash = function_coverage.source_hash();
let (expressions, counter_regions) =
function_coverage.get_expressions_and_counter_regions();
@ -228,3 +235,137 @@ fn save_function_record(
let is_used = true;
coverageinfo::save_func_record_to_mod(cx, func_name_hash, func_record_val, is_used);
}
/// When finalizing the coverage map, `FunctionCoverage` only has the `CodeRegion`s and counters for
/// the functions that went through codegen; such as public functions and "used" functions
/// (functions referenced by other "used" or public items). Any other functions considered unused,
/// or "Unreachable" were still parsed and processed through the MIR stage.
///
/// We can find the unreachable functions by the set different of all MIR `DefId`s (`tcx` query
/// `mir_keys`) minus the codegenned `DefId`s (`tcx` query `collect_and_partition_mono_items`).
///
/// *HOWEVER* the codegenned `DefId`s are partitioned across multiple `CodegenUnit`s (CGUs), and
/// this function is processing a `function_coverage_map` for the functions (`Instance`/`DefId`)
/// allocated to only one of those CGUs. We must NOT inject any "Unreachable" functions's
/// `CodeRegion`s more than once, so we have to pick which CGU's `function_coverage_map` to add
/// each "Unreachable" function to.
///
/// Some constraints:
///
/// 1. The file name of an "Unreachable" function must match the file name of the existing
/// codegenned (covered) function to which the unreachable code regions will be added.
/// 2. The function to which the unreachable code regions will be added must not be a genaric
/// function (must not have type parameters) because the coverage tools will get confused
/// if the codegenned function has more than one instantiation and additional `CodeRegion`s
/// attached to only one of those instantiations.
fn add_unreachable_coverage<'tcx>(
tcx: TyCtxt<'tcx>,
function_coverage_map: &mut FxHashMap<Instance<'tcx>, FunctionCoverage<'tcx>>,
) {
// Note: If the crate *only* defines generic functions, there are no codegenerated non-generic
// functions to add any unreachable code to. In this case, the unreachable code regions will
// have no coverage, instead of having coverage with zero executions.
//
// This is probably still an improvement over Clang, which does not generate any coverage
// for uninstantiated template functions.
let has_non_generic_def_ids =
function_coverage_map.keys().any(|instance| instance.def.attrs(tcx).len() == 0);
if !has_non_generic_def_ids {
// There are no non-generic functions to add unreachable `CodeRegion`s to
return;
}
let all_def_ids: DefIdSet =
tcx.mir_keys(LOCAL_CRATE).iter().map(|local_def_id| local_def_id.to_def_id()).collect();
let (codegenned_def_ids, _) = tcx.collect_and_partition_mono_items(LOCAL_CRATE);
let mut unreachable_def_ids_by_file: FxHashMap<Symbol, Vec<DefId>> = FxHashMap::default();
for &non_codegenned_def_id in all_def_ids.difference(codegenned_def_ids) {
// Make sure the non-codegenned (unreachable) function has a file_name
if let Some(non_codegenned_file_name) = tcx.covered_file_name(non_codegenned_def_id) {
let def_ids = unreachable_def_ids_by_file
.entry(*non_codegenned_file_name)
.or_insert_with(|| Vec::new());
def_ids.push(non_codegenned_def_id);
}
}
if unreachable_def_ids_by_file.is_empty() {
// There are no unreachable functions with file names to add (in any CGU)
return;
}
// Since there may be multiple `CodegenUnit`s, some codegenned_def_ids may be codegenned in a
// different CGU, and will be added to the function_coverage_map for each CGU. Determine which
// function_coverage_map has the responsibility for publishing unreachable coverage
// based on file name:
//
// For each covered file name, sort ONLY the non-generic codegenned_def_ids, and if
// covered_def_ids.contains(the first def_id) for a given file_name, add the unreachable code
// region in this function_coverage_map. Otherwise, ignore it and assume another CGU's
// function_coverage_map will be adding it (because it will be first for one, and only one,
// of them).
let mut sorted_codegenned_def_ids: Vec<DefId> =
codegenned_def_ids.iter().map(|def_id| *def_id).collect();
sorted_codegenned_def_ids.sort_unstable();
let mut first_covered_def_id_by_file: FxHashMap<Symbol, DefId> = FxHashMap::default();
for &def_id in sorted_codegenned_def_ids.iter() {
// Only consider non-generic functions, to potentially add unreachable code regions
if tcx.generics_of(def_id).count() == 0 {
if let Some(covered_file_name) = tcx.covered_file_name(def_id) {
// Only add files known to have unreachable functions
if unreachable_def_ids_by_file.contains_key(covered_file_name) {
first_covered_def_id_by_file.entry(*covered_file_name).or_insert(def_id);
}
}
}
}
// Get the set of def_ids with coverage regions, known by *this* CoverageContext.
let cgu_covered_def_ids: DefIdSet =
function_coverage_map.keys().map(|instance| instance.def.def_id()).collect();
let mut cgu_covered_files: FxHashSet<Symbol> = first_covered_def_id_by_file
.iter()
.filter_map(
|(&file_name, def_id)| {
if cgu_covered_def_ids.contains(def_id) { Some(file_name) } else { None }
},
)
.collect();
// Find the first covered, non-generic function (instance) for each cgu_covered_file. Take the
// unreachable code regions for that file, and add them to the function.
//
// There are three `for` loops here, but (a) the lists have already been reduced to the minimum
// required values, the lists are further reduced (by `remove()` calls) when elements are no
// longer needed, and there are several opportunities to branch out of loops early.
for (instance, function_coverage) in function_coverage_map.iter_mut() {
if instance.def.attrs(tcx).len() > 0 {
continue;
}
// The covered function is not generic...
let covered_def_id = instance.def.def_id();
if let Some(covered_file_name) = tcx.covered_file_name(covered_def_id) {
if !cgu_covered_files.remove(&covered_file_name) {
continue;
}
// The covered function's file is one of the files with unreachable code regions, so
// all of the unreachable code regions for this file will be added to this function.
for def_id in
unreachable_def_ids_by_file.remove(&covered_file_name).into_iter().flatten()
{
for &region in tcx.covered_code_regions(def_id) {
function_coverage.add_unreachable_region(region.clone());
}
}
if cgu_covered_files.is_empty() {
break;
}
}
}
}

View file

@ -2,6 +2,7 @@
#![feature(bool_to_option)]
#![feature(option_expect_none)]
#![feature(box_patterns)]
#![feature(drain_filter)]
#![feature(try_blocks)]
#![feature(in_band_lifetimes)]
#![feature(nll)]

View file

@ -32,6 +32,7 @@ macro_rules! arena_types {
[decode] borrowck_result:
rustc_middle::mir::BorrowCheckResult<$tcx>,
[decode] unsafety_check_result: rustc_middle::mir::UnsafetyCheckResult,
[decode] code_region: rustc_middle::mir::coverage::CodeRegion,
[] const_allocs: rustc_middle::mir::interpret::Allocation,
// Required for the incremental on-disk cache
[few] mir_keys: rustc_hir::def_id::DefIdSet,

View file

@ -47,7 +47,7 @@ fn fn_decl<'hir>(node: Node<'hir>) -> Option<&'hir FnDecl<'hir>> {
}
}
fn fn_sig<'hir>(node: Node<'hir>) -> Option<&'hir FnSig<'hir>> {
pub fn fn_sig<'hir>(node: Node<'hir>) -> Option<&'hir FnSig<'hir>> {
match &node {
Node::Item(Item { kind: ItemKind::Fn(sig, _, _), .. })
| Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(sig, _), .. })

View file

@ -346,6 +346,21 @@ rustc_queries! {
cache_on_disk_if { key.is_local() }
}
/// Returns the name of the file that contains the function body, if instrumented for coverage.
query covered_file_name(key: DefId) -> Option<Symbol> {
desc { |tcx| "retrieving the covered file name, if instrumented, for `{}`", tcx.def_path_str(key) }
storage(ArenaCacheSelector<'tcx>)
cache_on_disk_if { key.is_local() }
}
/// Returns the `CodeRegions` for a function that has instrumented coverage, in case the
/// function was optimized out before codegen, and before being added to the Coverage Map.
query covered_code_regions(key: DefId) -> Vec<&'tcx mir::coverage::CodeRegion> {
desc { |tcx| "retrieving the covered `CodeRegion`s, if instrumented, for `{}`", tcx.def_path_str(key) }
storage(ArenaCacheSelector<'tcx>)
cache_on_disk_if { key.is_local() }
}
/// The `DefId` is the `DefId` of the containing MIR body. Promoteds do not have their own
/// `DefId`. This function returns all promoteds in the specified body. The body references
/// promoteds by the `DefId` and the `mir::Promoted` index. This is necessary, because

View file

@ -162,7 +162,8 @@ encodable_via_deref! {
ty::Region<'tcx>,
&'tcx mir::Body<'tcx>,
&'tcx mir::UnsafetyCheckResult,
&'tcx mir::BorrowCheckResult<'tcx>
&'tcx mir::BorrowCheckResult<'tcx>,
&'tcx mir::coverage::CodeRegion
}
pub trait TyDecoder<'tcx>: Decoder {
@ -376,7 +377,8 @@ impl_decodable_via_ref! {
&'tcx Allocation,
&'tcx mir::Body<'tcx>,
&'tcx mir::UnsafetyCheckResult,
&'tcx mir::BorrowCheckResult<'tcx>
&'tcx mir::BorrowCheckResult<'tcx>,
&'tcx mir::coverage::CodeRegion
}
#[macro_export]

View file

@ -118,18 +118,8 @@ impl CoverageGraph {
match term.kind {
TerminatorKind::Return { .. }
// FIXME(richkadel): Add test(s) for `Abort` coverage.
| TerminatorKind::Abort
// FIXME(richkadel): Add test(s) for `Assert` coverage.
// Should `Assert` be handled like `FalseUnwind` instead? Since we filter out unwind
// branches when creating the BCB CFG, aren't `Assert`s (without unwinds) just like
// `FalseUnwinds` (which are kind of like `Goto`s)?
| TerminatorKind::Assert { .. }
// FIXME(richkadel): Add test(s) for `Yield` coverage, and confirm coverage is
// sensible for code using the `yield` keyword.
| TerminatorKind::Yield { .. }
// FIXME(richkadel): Also add coverage tests using async/await, and threading.
| TerminatorKind::SwitchInt { .. } => {
// The `bb` has more than one _outgoing_ edge, or exits the function. Save the
// current sequence of `basic_blocks` gathered to this point, as a new
@ -147,6 +137,14 @@ impl CoverageGraph {
// `Terminator`s `successors()` list) checking the number of successors won't
// work.
}
// The following `TerminatorKind`s are either not expected outside an unwind branch,
// or they should not (under normal circumstances) branch. Coverage graphs are
// simplified by assuring coverage results are accurate for well-behaved programs.
// Programs that panic and unwind may record slightly inaccurate coverage results
// for a coverage region containing the `Terminator` that began the panic. This
// is as intended. (See Issue #78544 for a possible future option to support
// coverage in test programs that panic.)
TerminatorKind::Goto { .. }
| TerminatorKind::Resume
| TerminatorKind::Unreachable
@ -154,6 +152,7 @@ impl CoverageGraph {
| TerminatorKind::DropAndReplace { .. }
| TerminatorKind::Call { .. }
| TerminatorKind::GeneratorDrop
| TerminatorKind::Assert { .. }
| TerminatorKind::FalseEdge { .. }
| TerminatorKind::FalseUnwind { .. }
| TerminatorKind::InlineAsm { .. } => {}
@ -278,6 +277,7 @@ rustc_index::newtype_index! {
/// A node in the [control-flow graph][CFG] of CoverageGraph.
pub(super) struct BasicCoverageBlock {
DEBUG_FORMAT = "bcb{}",
const START_BCB = 0,
}
}

View file

@ -88,6 +88,7 @@ struct Instrumentor<'a, 'tcx> {
pass_name: &'a str,
tcx: TyCtxt<'tcx>,
mir_body: &'a mut mir::Body<'tcx>,
fn_sig_span: Span,
body_span: Span,
basic_coverage_blocks: CoverageGraph,
coverage_counters: CoverageCounters,
@ -95,14 +96,19 @@ struct Instrumentor<'a, 'tcx> {
impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
fn new(pass_name: &'a str, tcx: TyCtxt<'tcx>, mir_body: &'a mut mir::Body<'tcx>) -> Self {
let hir_body = hir_body(tcx, mir_body.source.def_id());
let (some_fn_sig, hir_body) = fn_sig_and_body(tcx, mir_body.source.def_id());
let body_span = hir_body.value.span;
let fn_sig_span = match some_fn_sig {
Some(fn_sig) => fn_sig.span.with_hi(body_span.lo()),
None => body_span.shrink_to_lo(),
};
let function_source_hash = hash_mir_source(tcx, hir_body);
let basic_coverage_blocks = CoverageGraph::from_mir(mir_body);
Self {
pass_name,
tcx,
mir_body,
fn_sig_span,
body_span,
basic_coverage_blocks,
coverage_counters: CoverageCounters::new(function_source_hash),
@ -114,9 +120,15 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
let source_map = tcx.sess.source_map();
let mir_source = self.mir_body.source;
let def_id = mir_source.def_id();
let fn_sig_span = self.fn_sig_span;
let body_span = self.body_span;
debug!("instrumenting {:?}, span: {}", def_id, source_map.span_to_string(body_span));
debug!(
"instrumenting {:?}, fn sig span: {}, body span: {}",
def_id,
source_map.span_to_string(fn_sig_span),
source_map.span_to_string(body_span)
);
let mut graphviz_data = debug::GraphvizData::new();
let mut debug_used_expressions = debug::UsedExpressions::new();
@ -138,6 +150,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
// Compute `CoverageSpan`s from the `CoverageGraph`.
let coverage_spans = CoverageSpans::generate_coverage_spans(
&self.mir_body,
fn_sig_span,
body_span,
&self.basic_coverage_blocks,
);
@ -272,49 +285,15 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
bug!("Every BasicCoverageBlock should have a Counter or Expression");
};
graphviz_data.add_bcb_coverage_span_with_counter(bcb, &covspan, &counter_kind);
// FIXME(#78542): Can spans for `TerminatorKind::Goto` be improved to avoid special
// cases?
let some_code_region = if self.is_code_region_redundant(bcb, span, body_span) {
None
} else {
Some(make_code_region(file_name, &source_file, span, body_span))
};
inject_statement(self.mir_body, counter_kind, self.bcb_last_bb(bcb), some_code_region);
inject_statement(
self.mir_body,
counter_kind,
self.bcb_last_bb(bcb),
Some(make_code_region(file_name, &source_file, span, body_span)),
);
}
}
/// Returns true if the type of `BasicCoverageBlock` (specifically, it's `BasicBlock`s
/// `TerminatorKind`) with the given `Span` (relative to the `body_span`) is known to produce
/// a redundant coverage count.
///
/// There is at least one case for this, and if it's not handled, the last line in a function
/// will be double-counted.
///
/// If this method returns `true`, the counter (which other `Expressions` may depend on) is
/// still injected, but without an associated code region.
// FIXME(#78542): Can spans for `TerminatorKind::Goto` be improved to avoid special cases?
fn is_code_region_redundant(
&self,
bcb: BasicCoverageBlock,
span: Span,
body_span: Span,
) -> bool {
if span.hi() == body_span.hi() {
// All functions execute a `Return`-terminated `BasicBlock`, regardless of how the
// function returns; but only some functions also _can_ return after a `Goto` block
// that ends on the closing brace of the function (with the `Return`). When this
// happens, the last character is counted 2 (or possibly more) times, when we know
// the function returned only once (of course). By giving all `Goto` terminators at
// the end of a function a `non-reportable` code region, they are still counted
// if appropriate, but they don't increment the line counter, as long as their is
// also a `Return` on that last line.
if let TerminatorKind::Goto { .. } = self.bcb_terminator(bcb).kind {
return true;
}
}
false
}
/// `inject_coverage_span_counters()` looped through the `CoverageSpan`s and injected the
/// counter from the `CoverageSpan`s `BasicCoverageBlock`, removing it from the BCB in the
/// process (via `take_counter()`).
@ -411,11 +390,6 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
self.bcb_data(bcb).last_bb()
}
#[inline]
fn bcb_terminator(&self, bcb: BasicCoverageBlock) -> &Terminator<'tcx> {
self.bcb_data(bcb).terminator(self.mir_body)
}
#[inline]
fn bcb_data(&self, bcb: BasicCoverageBlock) -> &BasicCoverageBlockData {
&self.basic_coverage_blocks[bcb]
@ -521,10 +495,13 @@ fn make_code_region(
}
}
fn hir_body<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx rustc_hir::Body<'tcx> {
fn fn_sig_and_body<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: DefId,
) -> (Option<&'tcx rustc_hir::FnSig<'tcx>>, &'tcx rustc_hir::Body<'tcx>) {
let hir_node = tcx.hir().get_if_local(def_id).expect("expected DefId is local");
let fn_body_id = hir::map::associated_body(hir_node).expect("HIR node is a function with body");
tcx.hir().body(fn_body_id)
(hir::map::fn_sig(hir_node), tcx.hir().body(fn_body_id))
}
fn hash_mir_source<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &'tcx rustc_hir::Body<'tcx>) -> u64 {

View file

@ -1,6 +1,8 @@
use super::*;
use rustc_middle::mir::coverage::*;
use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::{Coverage, CoverageInfo, Location};
use rustc_middle::mir::{self, Coverage, CoverageInfo, Location};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_span::def_id::DefId;
@ -9,6 +11,8 @@ use rustc_span::def_id::DefId;
/// counter) and `FunctionCoverage::new()` (to extract the coverage map metadata from the MIR).
pub(crate) fn provide(providers: &mut Providers) {
providers.coverageinfo = |tcx, def_id| coverageinfo_from_mir(tcx, def_id);
providers.covered_file_name = |tcx, def_id| covered_file_name(tcx, def_id);
providers.covered_code_regions = |tcx, def_id| covered_code_regions(tcx, def_id);
}
/// The `num_counters` argument to `llvm.instrprof.increment` is the max counter_id + 1, or in
@ -123,3 +127,34 @@ fn coverageinfo_from_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> CoverageInfo
coverage_visitor.info
}
fn covered_file_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<Symbol> {
let mir_body = tcx.optimized_mir(def_id);
for bb_data in mir_body.basic_blocks().iter() {
for statement in bb_data.statements.iter() {
if let StatementKind::Coverage(box ref coverage) = statement.kind {
if let Some(code_region) = coverage.code_region.as_ref() {
return Some(code_region.file_name);
}
}
}
}
None
}
fn covered_code_regions<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Vec<&'tcx CodeRegion> {
let mir_body: &'tcx mir::Body<'tcx> = tcx.optimized_mir(def_id);
mir_body
.basic_blocks()
.iter()
.map(|data| {
data.statements.iter().filter_map(|statement| match statement.kind {
StatementKind::Coverage(box ref coverage) => {
coverage.code_region.as_ref() // may be None
}
_ => None,
})
})
.flatten()
.collect()
}

View file

@ -1,10 +1,9 @@
use super::debug::term_type;
use super::graph::{BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph};
use super::graph::{BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph, START_BCB};
use crate::util::spanview::source_range_no_file;
use rustc_data_structures::graph::WithNumNodes;
use rustc_index::bit_set::BitSet;
use rustc_middle::mir::{
self, AggregateKind, BasicBlock, FakeReadCause, Rvalue, Statement, StatementKind, Terminator,
TerminatorKind,
@ -74,6 +73,10 @@ pub(super) struct CoverageSpan {
}
impl CoverageSpan {
pub fn for_fn_sig(fn_sig_span: Span) -> Self {
Self { span: fn_sig_span, bcb: START_BCB, coverage_statements: vec![], is_closure: false }
}
pub fn for_statement(
statement: &Statement<'tcx>,
span: Span,
@ -82,10 +85,10 @@ impl CoverageSpan {
stmt_index: usize,
) -> Self {
let is_closure = match statement.kind {
StatementKind::Assign(box (
_,
Rvalue::Aggregate(box AggregateKind::Closure(_, _), _),
)) => true,
StatementKind::Assign(box (_, Rvalue::Aggregate(box ref kind, _))) => match kind {
AggregateKind::Closure(_, _) | AggregateKind::Generator(_, _, _) => true,
_ => false,
},
_ => false,
};
@ -109,9 +112,6 @@ impl CoverageSpan {
pub fn merge_from(&mut self, mut other: CoverageSpan) {
debug_assert!(self.is_mergeable(&other));
self.span = self.span.to(other.span);
if other.is_closure {
self.is_closure = true;
}
self.coverage_statements.append(&mut other.coverage_statements);
}
@ -171,6 +171,9 @@ pub struct CoverageSpans<'a, 'tcx> {
/// The MIR, used to look up `BasicBlockData`.
mir_body: &'a mir::Body<'tcx>,
/// A `Span` covering the signature of function for the MIR.
fn_sig_span: Span,
/// A `Span` covering the function body of the MIR (typically from left curly brace to right
/// curly brace).
body_span: Span,
@ -216,11 +219,13 @@ pub struct CoverageSpans<'a, 'tcx> {
impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
pub(super) fn generate_coverage_spans(
mir_body: &'a mir::Body<'tcx>,
fn_sig_span: Span,
body_span: Span,
basic_coverage_blocks: &'a CoverageGraph,
) -> Vec<CoverageSpan> {
let mut coverage_spans = CoverageSpans {
mir_body,
fn_sig_span,
body_span,
basic_coverage_blocks,
sorted_spans_iter: None,
@ -277,6 +282,8 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
return initial_spans;
}
initial_spans.push(CoverageSpan::for_fn_sig(self.fn_sig_span));
initial_spans.sort_unstable_by(|a, b| {
if a.span.lo() == b.span.lo() {
if a.span.hi() == b.span.hi() {
@ -331,7 +338,7 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
prev={:?}",
self.prev()
);
self.discard_curr();
self.take_curr();
} else if self.curr().is_closure {
self.carve_out_span_for_closure();
} else if self.prev_original_span == self.curr().span {
@ -345,28 +352,28 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
debug!(" AT END, adding last prev={:?}", self.prev());
let prev = self.take_prev();
let CoverageSpans {
mir_body, basic_coverage_blocks, pending_dups, mut refined_spans, ..
} = self;
let CoverageSpans { pending_dups, mut refined_spans, .. } = self;
for dup in pending_dups {
debug!(" ...adding at least one pending dup={:?}", dup);
refined_spans.push(dup);
}
refined_spans.push(prev);
// Remove `CoverageSpan`s with empty spans ONLY if the empty `CoverageSpan`s BCB also has at
// least one other non-empty `CoverageSpan`.
let mut has_coverage = BitSet::new_empty(basic_coverage_blocks.num_nodes());
for covspan in &refined_spans {
if !covspan.span.is_empty() {
has_coverage.insert(covspan.bcb);
}
// Async functions wrap a closure that implements the body to be executed. The enclosing
// function is initially called, posts the closure to the executor, and returns. To avoid
// showing the return from the enclosing function as a "covered" return from the closure,
// the enclosing function's `TerminatorKind::Return`s `CoverageSpan` is excluded. The
// closure's `Return` is the only one that will be counted. This provides adequate
// coverage, and more intuitive counts. (Avoids double-counting the closing brace of the
// function body.)
let body_ends_with_closure = if let Some(last_covspan) = refined_spans.last() {
last_covspan.is_closure && last_covspan.span.hi() == self.body_span.hi()
} else {
false
};
if !body_ends_with_closure {
refined_spans.push(prev);
}
refined_spans.retain(|covspan| {
!(covspan.span.is_empty()
&& is_goto(&basic_coverage_blocks[covspan.bcb].terminator(mir_body).kind)
&& has_coverage.contains(covspan.bcb))
});
// Remove `CoverageSpan`s derived from closures, originally added to ensure the coverage
// regions for the current function leave room for the closure's own coverage regions
@ -491,8 +498,8 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
/// If called, then the next call to `next_coverage_span()` will *not* update `prev` with the
/// `curr` coverage span.
fn discard_curr(&mut self) {
self.some_curr = None;
fn take_curr(&mut self) -> CoverageSpan {
self.some_curr.take().unwrap_or_else(|| bug!("invalid attempt to unwrap a None some_curr"))
}
/// Returns true if the curr span should be skipped because prev has already advanced beyond the
@ -508,11 +515,11 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
self.prev().span.hi() <= self.curr().span.lo()
}
/// If `prev`s span extends left of the closure (`curr`), carve out the closure's
/// span from `prev`'s span. (The closure's coverage counters will be injected when
/// processing the closure's own MIR.) Add the portion of the span to the left of the
/// closure; and if the span extends to the right of the closure, update `prev` to
/// that portion of the span. For any `pending_dups`, repeat the same process.
/// If `prev`s span extends left of the closure (`curr`), carve out the closure's span from
/// `prev`'s span. (The closure's coverage counters will be injected when processing the
/// closure's own MIR.) Add the portion of the span to the left of the closure; and if the span
/// extends to the right of the closure, update `prev` to that portion of the span. For any
/// `pending_dups`, repeat the same process.
fn carve_out_span_for_closure(&mut self) {
let curr_span = self.curr().span;
let left_cutoff = curr_span.lo();
@ -541,7 +548,8 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
dup.span = dup.span.with_lo(right_cutoff);
}
self.pending_dups.append(&mut pending_dups);
self.discard_curr(); // since self.prev() was already updated
let closure_covspan = self.take_curr();
self.refined_spans.push(closure_covspan); // since self.prev() was already updated
} else {
pending_dups.clear();
}
@ -705,30 +713,8 @@ pub(super) fn filtered_terminator_span(
| TerminatorKind::DropAndReplace { .. }
| TerminatorKind::SwitchInt { .. }
// For `FalseEdge`, only the `real` branch is taken, so it is similar to a `Goto`.
// FIXME(richkadel): Note that `Goto` was moved to it's own match arm, for the reasons
// described below. Add tests to confirm whether or not similar cases also apply to
// `FalseEdge`.
| TerminatorKind::FalseEdge { .. } => None,
// FIXME(#78542): Can spans for `TerminatorKind::Goto` be improved to avoid special cases?
//
// `Goto`s are often the targets of `SwitchInt` branches, and certain important
// optimizations to replace some `Counter`s with `Expression`s require a separate
// `BasicCoverageBlock` for each branch, to support the `Counter`, when needed.
//
// Also, some test cases showed that `Goto` terminators, and to some degree their `Span`s,
// provided useful context for coverage, such as to count and show when `if` blocks
// _without_ `else` blocks execute the `false` case (counting when the body of the `if`
// was _not_ taken). In these cases, the `Goto` span is ultimately given a `CoverageSpan`
// of 1 character, at the end of it's original `Span`.
//
// However, in other cases, a visible `CoverageSpan` is not wanted, but the `Goto`
// block must still be counted (for example, to contribute its count to an `Expression`
// that reports the execution count for some other block). In these cases, the code region
// is set to `None`. (See `Instrumentor::is_code_region_redundant()`.)
TerminatorKind::Goto { .. } => {
Some(function_source_span(terminator.source_info.span.shrink_to_hi(), body_span))
}
| TerminatorKind::FalseEdge { .. }
| TerminatorKind::Goto { .. } => None,
// Retain spans from all other terminators
TerminatorKind::Resume
@ -749,11 +735,3 @@ fn function_source_span(span: Span, body_span: Span) -> Span {
let span = original_sp(span, body_span).with_ctxt(SyntaxContext::root());
if body_span.contains(span) { span } else { body_span }
}
#[inline(always)]
fn is_goto(term_kind: &TerminatorKind<'tcx>) -> bool {
match term_kind {
TerminatorKind::Goto { .. } => true,
_ => false,
}
}

View file

@ -945,8 +945,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"instrument the generated code to support LLVM source-based code coverage \
reports (note, the compiler build config must include `profiler = true`, \
and is mutually exclusive with `-C profile-generate`/`-C profile-use`); \
implies `-C link-dead-code` (unless targeting MSVC, or explicitly disabled) \
and `-Z symbol-mangling-version=v0`; disables/overrides some Rust \
implies `-Z symbol-mangling-version=v0`; disables/overrides some Rust \
optimizations (default: no)"),
instrument_mcount: bool = (false, parse_bool, [TRACKED],
"insert function instrument code for mcount-based tracing (default: no)"),

View file

@ -1111,33 +1111,7 @@ impl Session {
pub fn link_dead_code(&self) -> bool {
match self.opts.cg.link_dead_code {
Some(explicitly_set) => explicitly_set,
None => {
self.opts.debugging_opts.instrument_coverage && !self.target.is_like_msvc
// Issue #76038: (rustc `-Clink-dead-code` causes MSVC linker to produce invalid
// binaries when LLVM InstrProf counters are enabled). As described by this issue,
// the "link dead code" option produces incorrect binaries when compiled and linked
// under MSVC. The resulting Rust programs typically crash with a segmentation
// fault, or produce an empty "*.profraw" file (profiling counter results normally
// generated during program exit).
//
// If not targeting MSVC, `-Z instrument-coverage` implies `-C link-dead-code`, so
// unexecuted code is still counted as zero, rather than be optimized out. Note that
// instrumenting dead code can be explicitly disabled with:
//
// `-Z instrument-coverage -C link-dead-code=no`.
//
// FIXME(richkadel): Investigate if `instrument-coverage` implementation can inject
// [zero counters](https://llvm.org/docs/CoverageMappingFormat.html#counter) in the
// coverage map when "dead code" is removed, rather than forcing `link-dead-code`.
// This may not be possible, however, if (as it seems to appear) the "dead code"
// that would otherwise not be linked is only identified as "dead" by the native
// linker. If that's the case, I believe it is too late for the Rust compiler to
// leverage any information it might be able to get from the linker regarding what
// code is dead, to be able to add those counters.
//
// On the other hand, if any Rust compiler passes are optimizing out dead code blocks
// we should inject "zero" counters for those code regions.
}
None => false,
}
}

View file

@ -1,6 +1,6 @@
# `source-based-code-coverage`
The tracking issue for this feature is: [#79121](https://github.com/rust-lang/rust/issues/79121).
The tracking issue for this feature is: [#79121].
------------------------
@ -8,7 +8,7 @@ The tracking issue for this feature is: [#79121](https://github.com/rust-lang/ru
The Rust compiler includes two code coverage implementations:
* A GCC-compatible, gcov-based coverage implementation, enabled with [`-Zprofile`](profile.md), which operates on DebugInfo.
* A GCC-compatible, gcov-based coverage implementation, enabled with [`-Zprofile`], which operates on DebugInfo.
* A source-based code coverage implementation, enabled with `-Zinstrument-coverage`, which uses LLVM's native coverage instrumentation to generate very precise coverage data.
This document describes how to enable and use the LLVM instrumentation-based coverage, via the `-Zinstrument-coverage` compiler flag.
@ -18,7 +18,7 @@ This document describes how to enable and use the LLVM instrumentation-based cov
When `-Zinstrument-coverage` is enabled, the Rust compiler enhances rust-based libraries and binaries by:
* Automatically injecting calls to an LLVM intrinsic ([`llvm.instrprof.increment`]), at functions and branches in compiled code, to increment counters when conditional sections of code are executed.
* Embedding additional information in the data section of each library and binary (using the [LLVM Code Coverage Mapping Format]), to define the code regions (start and end positions in the source code) being counted.
* Embedding additional information in the data section of each library and binary (using the [LLVM Code Coverage Mapping Format] _Version 4_, supported _only_ in LLVM 11 and up), to define the code regions (start and end positions in the source code) being counted.
When running a coverage-instrumented program, the counter values are written to a `profraw` file at program termination. LLVM bundles tools that read the counter results, combine those results with the coverage map (embedded in the program binary), and generate coverage reports in multiple formats.
@ -28,7 +28,7 @@ Rust's source-based code coverage requires the Rust "profiler runtime". Without
The Rust `nightly` distribution channel should include the profiler runtime, by default.
*IMPORTANT:* If you are building the Rust compiler from the source distribution, the profiler runtime is *not* enabled in the default `config.toml.example`, and may not be enabled in your `config.toml`. Edit the `config.toml` file, and find the `profiler` feature entry. Uncomment it and set it to `true`:
*IMPORTANT:* If you are building the Rust compiler from the source distribution, the profiler runtime is *not* enabled in the default `config.toml.example`. Edit your `config.toml` file and ensure the `profiler` feature is set it to `true`:
```toml
# Build the profiler runtime (required when compiling with options that depend
@ -36,13 +36,13 @@ The Rust `nightly` distribution channel should include the profiler runtime, by
profiler = true
```
Then rebuild the Rust compiler (see [rustc-dev-guide-how-to-build-and-run]).
If changed, rebuild the Rust compiler (see [rustc-dev-guide-how-to-build-and-run]).
### Building the demangler
LLVM coverage reporting tools generate results that can include function names and other symbol references, and the raw coverage results report symbols using the compiler's "mangled" version of the symbol names, which can be difficult to interpret. To work around this issue, LLVM coverage tools also support a user-specified symbol name demangler.
One option for a Rust demangler is [`rustfilt`](https://crates.io/crates/rustfilt), which can be installed with:
One option for a Rust demangler is [`rustfilt`], which can be installed with:
```shell
cargo install rustfilt
@ -68,7 +68,7 @@ $ cargo clean
$ RUSTFLAGS="-Zinstrument-coverage" cargo build
```
If `cargo` is not configured to use your `profiler`-enabled version of `rustc`, set the path explicitly via the `RUSTC` environment variable. Here is another example, using a `stage1` build of `rustc` to compile an `example` binary (from the [`json5format`](https://crates.io/crates/json5format) crate):
If `cargo` is not configured to use your `profiler`-enabled version of `rustc`, set the path explicitly via the `RUSTC` environment variable. Here is another example, using a `stage1` build of `rustc` to compile an `example` binary (from the [`json5format`] crate):
```shell
$ RUSTC=$HOME/rust/build/x86_64-unknown-linux-gnu/stage1/bin/rustc \
@ -108,19 +108,31 @@ If `LLVM_PROFILE_FILE` contains a path to a non-existent directory, the missing
* `%Nm` - the instrumented binarys signature: The runtime creates a pool of N raw profiles, used for on-line profile merging. The runtime takes care of selecting a raw profile from the pool, locking it, and updating it before the program exits. `N` must be between `1` and `9`, and defaults to `1` if omitted (with simply `%m`).
* `%c` - Does not add anything to the filename, but enables a mode (on some platforms, including Darwin) in which profile counter updates are continuously synced to a file. This means that if the instrumented program crashes, or is killed by a signal, perfect coverage information can still be recovered.
## Installing LLVM coverage tools
LLVM's supplies two tools—`llvm-profdata` and `llvm-cov`—that process coverage data and generate reports. There are several ways to find and/or install these tools, but note that the coverage mapping data generated by the Rust compiler requires LLVM version 11 or higher. (`llvm-cov --version` typically shows the tool's LLVM version number.):
* The LLVM tools may be installed (or installable) directly to your OS (such as via `apt-get`, for Linux).
* If you are building the Rust compiler from source, you can optionally use the bundled LLVM tools, built from source. Those tool binaries can typically be found in your build platform directory at something like: `rust/build/x86_64-unknown-linux-gnu/llvm/bin/llvm-*`.
* You can install compatible versions of these tools via `rustup`.
The `rustup` option is guaranteed to install a compatible version of the LLVM tools, but they can be hard to find. We recommend [`cargo-bintools`], which installs Rust-specific wrappers around these and other LLVM tools, so you can invoke them via `cargo` commands!
```shell
$ rustup component add llvm-tools-preview
$ cargo install cargo-binutils
$ cargo profdata -- --help # note the additional "--" preceeding the tool-specific arguments
```
## Creating coverage reports
LLVM's tools to process coverage data and coverage maps have some version dependencies. If you encounter a version mismatch, try updating your LLVM tools.
If you are building the Rust compiler from source, you can optionally use the bundled LLVM tools, built from source. Those tool binaries can typically be found in your build platform directory at something like: `rust/build/x86_64-unknown-linux-gnu/llvm/bin/llvm-*`. (Look for `llvm-profdata` and `llvm-cov`.)
Raw profiles have to be indexed before they can be used to generate coverage reports. This is done using [`llvm-profdata merge`] (which can combine multiple raw profiles and index them at the same time):
Raw profiles have to be indexed before they can be used to generate coverage reports. This is done using [`llvm-profdata merge`] (or `cargo cov -- merge`), which can combine multiple raw profiles and index them at the same time:
```shell
$ llvm-profdata merge -sparse formatjson5.profraw -o formatjson5.profdata
```
Finally, the `.profdata` file is used, in combination with the coverage map (from the program binary) to generate coverage reports using [`llvm-cov report`]--for a coverage summaries--and [`llvm-cov show`]--to see detailed coverage of lines and regions (character ranges), overlaid on the original source code.
Finally, the `.profdata` file is used, in combination with the coverage map (from the program binary) to generate coverage reports using [`llvm-cov report`] (or `cargo cov -- report`), for a coverage summaries; and [`llvm-cov show`] (or `cargo cov -- show`), to see detailed coverage of lines and regions (character ranges) overlaid on the original source code.
These commands have several display and filtering options. For example:
@ -154,14 +166,77 @@ There are four statistics tracked in a coverage summary:
Of these four statistics, function coverage is usually the least granular while region coverage is the most granular. The project-wide totals for each statistic are listed in the summary.
## Test coverage
A typical use case for coverage analysis is test coverage. Rust's source-based coverage tools can both measure your tests' code coverage as percentage, and pinpoint functions and branches not tested.
The following example (using the [`json5format`] crate, for demonstration purposes) show how to generate and analyze coverage results for all tests in a crate.
Since `cargo test` both builds and runs the tests, we set both the additional `RUSTFLAGS`, to add the `-Zinstrument-coverage` flag, and `LLVM_PROFILE_FILE`, to set a custom filename for the raw profiling data generated during the test runs. Since there may be more than one test binary, apply `%m` in the filename pattern. This generates unique names for each test binary. (Otherwise, each executed test binary would overwrite the coverage results from the previous binary.)
```shell
$ RUSTFLAGS="-Zinstrument-coverage" \
LLVM_PROFILE_FILE="json5format-%m.profraw" \
cargo test --tests
```
Make note of the test binary file paths, displayed after the word "`Running`" in the test output:
```text
...
Compiling json5format v0.1.3 ($HOME/json5format)
Finished test [unoptimized + debuginfo] target(s) in 14.60s
Running target/debug/deps/json5format-fececd4653271682
running 25 tests
...
test result: ok. 25 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/lib-30768f9c53506dc5
running 31 tests
...
test result: ok. 31 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
```
You should have one ore more `.profraw` files now, one for each test binary. Run the `profdata` tool to merge them:
```shell
$ cargo profdata -- merge \
-sparse json5format-*.profraw -o json5format.profdata
```
Then run the `cov` tool, with the `profdata` file and all test binaries:
```shell
$ cargo cov -- report \
--use-color --ignore-filename-regex='/.cargo/registry' \
--instr-profile=json5format.profdata \
target/debug/deps/lib-30768f9c53506dc5 \
target/debug/deps/json5format-fececd4653271682
$ cargo cov -- show \
--use-color --ignore-filename-regex='/.cargo/registry' \
--instr-profile=json5format.profdata \
target/debug/deps/lib-30768f9c53506dc5 \
target/debug/deps/json5format-fececd4653271682 \
--show-instantiations --show-line-counts-or-regions \
--Xdemangler=rustfilt | less -R
```
_Note the command line option `--ignore-filename-regex=/.cargo/registry`, which excludes the sources for dependencies from the coverage results._
## Other references
Rust's implementation and workflow for source-based code coverage is based on the same library and tools used to implement [source-based code coverage in Clang](https://clang.llvm.org/docs/SourceBasedCodeCoverage.html). (This document is partially based on the Clang guide.)
Rust's implementation and workflow for source-based code coverage is based on the same library and tools used to implement [source-based code coverage in Clang]. (This document is partially based on the Clang guide.)
[#34701]: https://github.com/rust-lang/rust/issues/34701
[#79121]: https://github.com/rust-lang/rust/issues/79121
[`-Zprofile`]: profile.md
[`llvm.instrprof.increment`]: https://llvm.org/docs/LangRef.html#llvm-instrprof-increment-intrinsic
[LLVM Code Coverage Mapping Format]: https://llvm.org/docs/CoverageMappingFormat.html
[rustc-dev-guide-how-to-build-and-run]: https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html
[`rustfilt`]: https://crates.io/crates/rustfilt
[`json5format`]: https://crates.io/crates/json5format
[`cargo-bintools`]: https://crates.io/crates/cargo-bintools
[`llvm-profdata merge`]: https://llvm.org/docs/CommandGuide/llvm-profdata.html#profdata-merge
[`llvm-cov report`]: https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-report
[`llvm-cov show`]: https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-show
[source-based code coverage in Clang]: https://clang.llvm.org/docs/SourceBasedCodeCoverage.html

View file

@ -15,7 +15,7 @@
}
bb1: {
_0 = const (); // scope 0 at $DIR/control-flow-simplification.rs:12:5: 14:6
_0 = const (); // scope 0 at $DIR/control-flow-simplification.rs:14:6: 14:6
StorageDead(_1); // scope 0 at $DIR/control-flow-simplification.rs:15:1: 15:2
return; // scope 0 at $DIR/control-flow-simplification.rs:15:2: 15:2
}

View file

@ -4,7 +4,7 @@ fn hello() -> () {
let mut _0: (); // return place in scope 0 at $DIR/control-flow-simplification.rs:11:14: 11:14
bb0: {
_0 = const (); // scope 0 at $DIR/control-flow-simplification.rs:12:5: 14:6
_0 = const (); // scope 0 at $DIR/control-flow-simplification.rs:14:6: 14:6
return; // scope 0 at $DIR/control-flow-simplification.rs:15:2: 15:2
}
}

View file

@ -2,5 +2,5 @@ digraph Cov_0_4 {
graph [fontname="Courier, monospace"];
node [fontname="Courier, monospace"];
edge [fontname="Courier, monospace"];
bcb0__Cov_0_4 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb0</td></tr><tr><td align="left" balign="left"></td></tr><tr><td align="left" balign="left">Counter(bcb0) at 19:5-20:2<br/> 19:5-19:9: @0[0]: _0 = const true<br/> 20:2-20:2: @0.Return: return</td></tr><tr><td align="left" balign="left">bb0: Return</td></tr></table>>];
bcb0__Cov_0_4 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb0</td></tr><tr><td align="left" balign="left"></td></tr><tr><td align="left" balign="left">Counter(bcb0) at 18:1-20:2<br/> 19:5-19:9: @0[0]: _0 = const true<br/> 20:2-20:2: @0.Return: return</td></tr><tr><td align="left" balign="left">bb0: Return</td></tr></table>>];
}

View file

@ -2,9 +2,9 @@ digraph Cov_0_3 {
graph [fontname="Courier, monospace"];
node [fontname="Courier, monospace"];
edge [fontname="Courier, monospace"];
bcb2__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb2</td></tr><tr><td align="left" balign="left">Expression(bcb0 - bcb1) at 14:6-14:6<br/> 14:6-14:6: @4.Goto: goto -&gt; bb0</td></tr><tr><td align="left" balign="left">bb4: Goto</td></tr></table>>];
bcb2__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb2</td></tr><tr><td align="left" balign="left">Expression(bcb0 - bcb1) at 13:10-13:10<br/> 13:10-13:10: @4[0]: _1 = const ()</td></tr><tr><td align="left" balign="left">bb4: Goto</td></tr></table>>];
bcb1__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb1</td></tr><tr><td align="left" balign="left">Counter(bcb1) at 12:13-12:18<br/> 12:13-12:18: @5[0]: _0 = const ()<br/>Expression(bcb1 + 0) at 15:2-15:2<br/> 15:2-15:2: @5.Return: return</td></tr><tr><td align="left" balign="left">bb3: FalseEdge</td></tr><tr><td align="left" balign="left">bb5: Return</td></tr></table>>];
bcb0__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb0</td></tr><tr><td align="left" balign="left"></td></tr><tr><td align="left" balign="left">Counter(bcb0) at 11:12-11:17<br/> 11:12-11:17: @1.Call: _2 = bar() -&gt; [return: bb2, unwind: bb6]<br/> 11:12-11:17: @2[0]: FakeRead(ForMatchedPlace, _2)</td></tr><tr><td align="left" balign="left">bb0: FalseUnwind<br/>bb1: Call</td></tr><tr><td align="left" balign="left">bb2: SwitchInt</td></tr></table>>];
bcb0__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb0</td></tr><tr><td align="left" balign="left"></td></tr><tr><td align="left" balign="left">Counter(bcb0) at 9:1-11:17<br/> 11:12-11:17: @1.Call: _2 = bar() -&gt; [return: bb2, unwind: bb6]<br/> 11:12-11:17: @2[0]: FakeRead(ForMatchedPlace, _2)</td></tr><tr><td align="left" balign="left">bb0: FalseUnwind<br/>bb1: Call</td></tr><tr><td align="left" balign="left">bb2: SwitchInt</td></tr></table>>];
bcb2__Cov_0_3 -> bcb0__Cov_0_3 [label=<>];
bcb0__Cov_0_3 -> bcb2__Cov_0_3 [label=<false>];
bcb0__Cov_0_3 -> bcb1__Cov_0_3 [label=<otherwise>];

View file

@ -57,7 +57,7 @@
}
bb1: {
_7 = const (); // scope 4 at $DIR/inst_combine_deref.rs:60:5: 60:23
_7 = const (); // scope 4 at $DIR/inst_combine_deref.rs:60:23: 60:23
StorageDead(_8); // scope 4 at $DIR/inst_combine_deref.rs:60:22: 60:23
StorageDead(_7); // scope 4 at $DIR/inst_combine_deref.rs:60:22: 60:23
_0 = const (); // scope 0 at $DIR/inst_combine_deref.rs:54:24: 61:2

View file

@ -6,7 +6,7 @@
bb0: {
_0 = const true; // scope 0 at /the/src/instrument_coverage.rs:20:5: 20:9
+ Coverage::Counter(1) for /the/src/instrument_coverage.rs:20:5 - 21:2; // scope 0 at /the/src/instrument_coverage.rs:21:2: 21:2
+ Coverage::Counter(1) for /the/src/instrument_coverage.rs:19:1 - 21:2; // scope 0 at /the/src/instrument_coverage.rs:21:2: 21:2
return; // scope 0 at /the/src/instrument_coverage.rs:21:2: 21:2
}
}

View file

@ -21,7 +21,7 @@
bb2: {
FakeRead(ForMatchedPlace, _2); // scope 0 at /the/src/instrument_coverage.rs:12:12: 12:17
+ Coverage::Counter(1) for /the/src/instrument_coverage.rs:12:12 - 12:17; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10
+ Coverage::Counter(1) for /the/src/instrument_coverage.rs:10:1 - 12:17; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10
switchInt(_2) -> [false: bb4, otherwise: bb3]; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10
}
@ -30,9 +30,9 @@
}
bb4: {
_1 = const (); // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10
_1 = const (); // scope 0 at /the/src/instrument_coverage.rs:14:10: 14:10
StorageDead(_2); // scope 0 at /the/src/instrument_coverage.rs:15:5: 15:6
+ Coverage::Expression(4294967295) = 1 - 2 for /the/src/instrument_coverage.rs:15:6 - 15:7; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6
+ Coverage::Expression(4294967295) = 1 - 2 for /the/src/instrument_coverage.rs:14:10 - 14:11; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6
goto -> bb0; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6
}

View file

@ -35,7 +35,7 @@ fn main() -> () {
}
bb4: {
_3 = const (); // scope 1 at $DIR/issue-38669.rs:7:9: 9:10
_3 = const (); // scope 1 at $DIR/issue-38669.rs:9:10: 9:10
StorageDead(_4); // scope 1 at $DIR/issue-38669.rs:9:9: 9:10
StorageDead(_3); // scope 1 at $DIR/issue-38669.rs:9:9: 9:10
_1 = const true; // scope 1 at $DIR/issue-38669.rs:10:9: 10:28

View file

@ -37,7 +37,7 @@ fn main() -> () {
}
bb2: {
_0 = const (); // scope 1 at $DIR/issue-41888.rs:8:5: 14:6
_0 = const (); // scope 1 at $DIR/issue-41888.rs:14:6: 14:6
goto -> bb8; // scope 1 at $DIR/issue-41888.rs:8:5: 14:6
}
@ -61,7 +61,7 @@ fn main() -> () {
}
bb6: {
_0 = const (); // scope 1 at $DIR/issue-41888.rs:10:9: 13:10
_0 = const (); // scope 1 at $DIR/issue-41888.rs:13:10: 13:10
goto -> bb8; // scope 1 at $DIR/issue-41888.rs:10:9: 13:10
}

View file

@ -25,7 +25,7 @@ fn main() -> () {
}
bb2: {
_1 = const (); // scope 0 at $DIR/loop_test.rs:10:5: 12:6
_1 = const (); // scope 0 at $DIR/loop_test.rs:12:6: 12:6
StorageDead(_2); // scope 0 at $DIR/loop_test.rs:12:5: 12:6
StorageDead(_1); // scope 0 at $DIR/loop_test.rs:12:5: 12:6
StorageLive(_4); // scope 0 at $DIR/loop_test.rs:13:5: 16:6

View file

@ -34,7 +34,7 @@
}
bb4: {
_0 = const (); // scope 0 at $DIR/matches_reduce_branches.rs:7:5: 9:6
_0 = const (); // scope 0 at $DIR/matches_reduce_branches.rs:9:6: 9:6
goto -> bb5; // scope 0 at $DIR/matches_reduce_branches.rs:7:5: 9:6
}

View file

@ -34,7 +34,7 @@
}
bb4: {
_0 = const (); // scope 0 at $DIR/matches_reduce_branches.rs:7:5: 9:6
_0 = const (); // scope 0 at $DIR/matches_reduce_branches.rs:9:6: 9:6
goto -> bb5; // scope 0 at $DIR/matches_reduce_branches.rs:7:5: 9:6
}

View file

@ -33,7 +33,7 @@
-
- bb4: {
+ bb2: {
_1 = const (); // scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10
_1 = const (); // scope 0 at $DIR/simplify_cfg.rs:9:10: 9:10
StorageDead(_2); // scope 0 at $DIR/simplify_cfg.rs:10:5: 10:6
goto -> bb0; // scope 0 at $DIR/simplify_cfg.rs:6:5: 10:6
}

View file

@ -40,7 +40,7 @@
- bb5: {
+ bb4: {
_1 = const (); // scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10
_1 = const (); // scope 0 at $DIR/simplify_cfg.rs:9:10: 9:10
- goto -> bb9; // scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10
+ StorageDead(_2); // scope 0 at $DIR/simplify_cfg.rs:10:5: 10:6
+ goto -> bb0; // scope 0 at $DIR/simplify_cfg.rs:6:5: 10:6

View file

@ -14,7 +14,7 @@
}
bb1: {
_0 = const (); // scope 0 at $DIR/simplify_if.rs:6:5: 8:6
_0 = const (); // scope 0 at $DIR/simplify_if.rs:8:6: 8:6
goto -> bb4; // scope 0 at $DIR/simplify_if.rs:6:5: 8:6
}

View file

@ -30,7 +30,7 @@
}
bb1: {
_0 = const (); // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:5: 8:6
_0 = const (); // scope 0 at $DIR/simplify-locals-fixedpoint.rs:8:6: 8:6
goto -> bb7; // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:5: 8:6
}
@ -51,7 +51,7 @@
}
bb4: {
_0 = const (); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:9: 7:10
_0 = const (); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:7:10: 7:10
goto -> bb6; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:9: 7:10
}

View file

@ -32,7 +32,7 @@
}
bb2: {
_0 = const (); // scope 0 at $DIR/unreachable.rs:9:5: 19:6
_0 = const (); // scope 0 at $DIR/unreachable.rs:19:6: 19:6
StorageDead(_1); // scope 0 at $DIR/unreachable.rs:20:1: 20:2
return; // scope 0 at $DIR/unreachable.rs:20:2: 20:2
- }

View file

@ -34,7 +34,7 @@
}
bb2: {
_0 = const (); // scope 0 at $DIR/unreachable_asm.rs:11:5: 23:6
_0 = const (); // scope 0 at $DIR/unreachable_asm.rs:23:6: 23:6
StorageDead(_1); // scope 0 at $DIR/unreachable_asm.rs:24:1: 24:2
return; // scope 0 at $DIR/unreachable_asm.rs:24:2: 24:2
}

View file

@ -37,7 +37,7 @@
}
bb2: {
_0 = const (); // scope 0 at $DIR/unreachable_asm_2.rs:11:5: 25:6
_0 = const (); // scope 0 at $DIR/unreachable_asm_2.rs:25:6: 25:6
StorageDead(_1); // scope 0 at $DIR/unreachable_asm_2.rs:26:1: 26:2
return; // scope 0 at $DIR/unreachable_asm_2.rs:26:2: 26:2
}

View file

@ -33,7 +33,7 @@
}
bb2: {
_0 = const (); // scope 1 at $DIR/unreachable_diverging.rs:14:5: 19:6
_0 = const (); // scope 1 at $DIR/unreachable_diverging.rs:19:6: 19:6
StorageDead(_1); // scope 0 at $DIR/unreachable_diverging.rs:20:1: 20:2
StorageDead(_2); // scope 0 at $DIR/unreachable_diverging.rs:20:1: 20:2
return; // scope 0 at $DIR/unreachable_diverging.rs:20:2: 20:2
@ -50,7 +50,7 @@
}
bb4: {
- _5 = const (); // scope 2 at $DIR/unreachable_diverging.rs:15:9: 17:10
- _5 = const (); // scope 2 at $DIR/unreachable_diverging.rs:17:10: 17:10
- goto -> bb6; // scope 2 at $DIR/unreachable_diverging.rs:15:9: 17:10
- }
-

View file

@ -1,11 +0,0 @@
# needs-profiler-support
# ignore-msvc
# LINK_DEAD_CODE requires ignore-msvc due to Issue #76038
LINK_DEAD_CODE=yes
-include ../coverage-llvmir/Makefile
# ISSUE(76038): When targeting MSVC, Rust binaries built with both `-Z instrument-coverage` and
# `-C link-dead-code` typically crash (with a seg-fault) or at best generate an empty `*.profraw`.
# See ../coverage/coverage_tools.mk for more information.

View file

@ -1,9 +1,5 @@
# needs-profiler-support
# ISSUE(76038): When targeting MSVC, Rust binaries built with both `-Z instrument-coverage` and
# `-C link-dead-code` typically crash (with a seg-fault) or at best generate an empty `*.profraw`.
# See ../coverage/coverage_tools.mk for more information.
-include ../coverage/coverage_tools.mk
BASEDIR=../coverage-llvmir
@ -20,11 +16,7 @@ else
COMDAT_IF_SUPPORTED=, comdat
endif
ifeq ($(LINK_DEAD_CODE),yes)
DEFINE_INTERNAL=define hidden
else
DEFINE_INTERNAL=define internal
endif
DEFINE_INTERNAL=define internal
ifdef IS_WINDOWS
LLVM_FILECHECK_OPTIONS=\
@ -65,14 +57,8 @@ endif
test_llvm_ir:
# Compile the test program with non-experimental coverage instrumentation, and generate LLVM IR
#
# Note: `-Clink-dead-code=no` disables the option, needed because the option is automatically
# enabled for some platforms, but not for Windows MSVC (due to Issue #76038). The state of this
# option affects the generated MIR and coverage, so it is enabled for tests to ensure the
# tests results are the same across platforms.
$(RUSTC) $(BASEDIR)/testprog.rs \
-Zinstrument-coverage \
-Clink-dead-code=$(LINK_DEAD_CODE) \
--emit=llvm-ir
cat "$(TMPDIR)"/testprog.ll | \

View file

@ -1,15 +0,0 @@
# needs-profiler-support
# ignore-msvc
# ignore-windows-gnu
# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works
# properly. Since we only have GCC on the CI ignore the test for now.
# LINK_DEAD_CODE requires ignore-msvc due to Issue #76038
LINK_DEAD_CODE=yes
-include ../coverage-reports/Makefile
# ISSUE(76038): When targeting MSVC, Rust binaries built with both `-Z instrument-coverage` and
# `-C link-dead-code` typically crash (with a seg-fault) or at best generate an empty `*.profraw`.
# See ../coverage/coverage_tools.mk for more information.

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/abort.rs",
"summary": {
"functions": {
"count": 2,
"covered": 2,
"percent": 100
},
"instantiations": {
"count": 2,
"covered": 2,
"percent": 100
},
"lines": {
"count": 15,
"covered": 13,
"percent": 86.66666666666667
},
"regions": {
"count": 10,
"covered": 9,
"notcovered": 1,
"percent": 90
}
}
}
],
"totals": {
"functions": {
"count": 2,
"covered": 2,
"percent": 100
},
"instantiations": {
"count": 2,
"covered": 2,
"percent": 100
},
"lines": {
"count": 15,
"covered": 13,
"percent": 86.66666666666667
},
"regions": {
"count": 10,
"covered": 9,
"notcovered": 1,
"percent": 90
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/assert.rs",
"summary": {
"functions": {
"count": 2,
"covered": 2,
"percent": 100
},
"instantiations": {
"count": 2,
"covered": 2,
"percent": 100
},
"lines": {
"count": 13,
"covered": 10,
"percent": 76.92307692307693
},
"regions": {
"count": 14,
"covered": 12,
"notcovered": 2,
"percent": 85.71428571428571
}
}
}
],
"totals": {
"functions": {
"count": 2,
"covered": 2,
"percent": 100
},
"instantiations": {
"count": 2,
"covered": 2,
"percent": 100
},
"lines": {
"count": 13,
"covered": 10,
"percent": 76.92307692307693
},
"regions": {
"count": 14,
"covered": 12,
"notcovered": 2,
"percent": 85.71428571428571
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/async.rs",
"summary": {
"functions": {
"count": 9,
"covered": 9,
"percent": 100
},
"instantiations": {
"count": 9,
"covered": 9,
"percent": 100
},
"lines": {
"count": 31,
"covered": 30,
"percent": 96.7741935483871
},
"regions": {
"count": 21,
"covered": 18,
"notcovered": 3,
"percent": 85.71428571428571
}
}
}
],
"totals": {
"functions": {
"count": 9,
"covered": 9,
"percent": 100
},
"instantiations": {
"count": 9,
"covered": 9,
"percent": 100
},
"lines": {
"count": 31,
"covered": 30,
"percent": 96.7741935483871
},
"regions": {
"count": 21,
"covered": 18,
"notcovered": 3,
"percent": 85.71428571428571
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/closure.rs",
"summary": {
"functions": {
"count": 5,
"covered": 3,
"percent": 60
},
"instantiations": {
"count": 5,
"covered": 3,
"percent": 60
},
"lines": {
"count": 91,
"covered": 77,
"percent": 84.61538461538461
},
"regions": {
"count": 25,
"covered": 13,
"notcovered": 12,
"percent": 52
}
}
}
],
"totals": {
"functions": {
"count": 5,
"covered": 3,
"percent": 60
},
"instantiations": {
"count": 5,
"covered": 3,
"percent": 60
},
"lines": {
"count": 91,
"covered": 77,
"percent": 84.61538461538461
},
"regions": {
"count": 25,
"covered": 13,
"notcovered": 12,
"percent": 52
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/conditions.rs",
"summary": {
"functions": {
"count": 1,
"covered": 1,
"percent": 100
},
"instantiations": {
"count": 1,
"covered": 1,
"percent": 100
},
"lines": {
"count": 64,
"covered": 33,
"percent": 51.5625
},
"regions": {
"count": 88,
"covered": 25,
"notcovered": 63,
"percent": 28.40909090909091
}
}
}
],
"totals": {
"functions": {
"count": 1,
"covered": 1,
"percent": 100
},
"instantiations": {
"count": 1,
"covered": 1,
"percent": 100
},
"lines": {
"count": 64,
"covered": 33,
"percent": 51.5625
},
"regions": {
"count": 88,
"covered": 25,
"notcovered": 63,
"percent": 28.40909090909091
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/drop_trait.rs",
"summary": {
"functions": {
"count": 2,
"covered": 2,
"percent": 100
},
"instantiations": {
"count": 2,
"covered": 2,
"percent": 100
},
"lines": {
"count": 10,
"covered": 10,
"percent": 100
},
"regions": {
"count": 5,
"covered": 5,
"notcovered": 0,
"percent": 100
}
}
}
],
"totals": {
"functions": {
"count": 2,
"covered": 2,
"percent": 100
},
"instantiations": {
"count": 2,
"covered": 2,
"percent": 100
},
"lines": {
"count": 10,
"covered": 10,
"percent": 100
},
"regions": {
"count": 5,
"covered": 5,
"notcovered": 0,
"percent": 100
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/generics.rs",
"summary": {
"functions": {
"count": 3,
"covered": 3,
"percent": 100
},
"instantiations": {
"count": 5,
"covered": 5,
"percent": 100
},
"lines": {
"count": 16,
"covered": 16,
"percent": 100
},
"regions": {
"count": 6,
"covered": 6,
"notcovered": 0,
"percent": 100
}
}
}
],
"totals": {
"functions": {
"count": 3,
"covered": 3,
"percent": 100
},
"instantiations": {
"count": 5,
"covered": 5,
"percent": 100
},
"lines": {
"count": 16,
"covered": 16,
"percent": 100
},
"regions": {
"count": 6,
"covered": 6,
"notcovered": 0,
"percent": 100
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/if.rs",
"summary": {
"functions": {
"count": 1,
"covered": 1,
"percent": 100
},
"instantiations": {
"count": 1,
"covered": 1,
"percent": 100
},
"lines": {
"count": 19,
"covered": 19,
"percent": 100
},
"regions": {
"count": 5,
"covered": 4,
"notcovered": 1,
"percent": 80
}
}
}
],
"totals": {
"functions": {
"count": 1,
"covered": 1,
"percent": 100
},
"instantiations": {
"count": 1,
"covered": 1,
"percent": 100
},
"lines": {
"count": 19,
"covered": 19,
"percent": 100
},
"regions": {
"count": 5,
"covered": 4,
"notcovered": 1,
"percent": 80
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/if_else.rs",
"summary": {
"functions": {
"count": 1,
"covered": 1,
"percent": 100
},
"instantiations": {
"count": 1,
"covered": 1,
"percent": 100
},
"lines": {
"count": 28,
"covered": 19,
"percent": 67.85714285714286
},
"regions": {
"count": 7,
"covered": 5,
"notcovered": 2,
"percent": 71.42857142857143
}
}
}
],
"totals": {
"functions": {
"count": 1,
"covered": 1,
"percent": 100
},
"instantiations": {
"count": 1,
"covered": 1,
"percent": 100
},
"lines": {
"count": 28,
"covered": 19,
"percent": 67.85714285714286
},
"regions": {
"count": 7,
"covered": 5,
"notcovered": 2,
"percent": 71.42857142857143
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/inner_items.rs",
"summary": {
"functions": {
"count": 4,
"covered": 4,
"percent": 100
},
"instantiations": {
"count": 4,
"covered": 4,
"percent": 100
},
"lines": {
"count": 27,
"covered": 27,
"percent": 100
},
"regions": {
"count": 11,
"covered": 9,
"notcovered": 2,
"percent": 81.81818181818183
}
}
}
],
"totals": {
"functions": {
"count": 4,
"covered": 4,
"percent": 100
},
"instantiations": {
"count": 4,
"covered": 4,
"percent": 100
},
"lines": {
"count": 27,
"covered": 27,
"percent": 100
},
"regions": {
"count": 11,
"covered": 9,
"notcovered": 2,
"percent": 81.81818181818183
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/lazy_boolean.rs",
"summary": {
"functions": {
"count": 1,
"covered": 1,
"percent": 100
},
"instantiations": {
"count": 1,
"covered": 1,
"percent": 100
},
"lines": {
"count": 40,
"covered": 30,
"percent": 75
},
"regions": {
"count": 37,
"covered": 26,
"notcovered": 11,
"percent": 70.27027027027027
}
}
}
],
"totals": {
"functions": {
"count": 1,
"covered": 1,
"percent": 100
},
"instantiations": {
"count": 1,
"covered": 1,
"percent": 100
},
"lines": {
"count": 40,
"covered": 30,
"percent": 75
},
"regions": {
"count": 37,
"covered": 26,
"notcovered": 11,
"percent": 70.27027027027027
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/loops_branches.rs",
"summary": {
"functions": {
"count": 2,
"covered": 2,
"percent": 100
},
"instantiations": {
"count": 2,
"covered": 2,
"percent": 100
},
"lines": {
"count": 11,
"covered": 11,
"percent": 100
},
"regions": {
"count": 9,
"covered": 8,
"notcovered": 1,
"percent": 88.88888888888889
}
}
}
],
"totals": {
"functions": {
"count": 2,
"covered": 2,
"percent": 100
},
"instantiations": {
"count": 2,
"covered": 2,
"percent": 100
},
"lines": {
"count": 11,
"covered": 11,
"percent": 100
},
"regions": {
"count": 9,
"covered": 8,
"notcovered": 1,
"percent": 88.88888888888889
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/nested_loops.rs",
"summary": {
"functions": {
"count": 1,
"covered": 1,
"percent": 100
},
"instantiations": {
"count": 1,
"covered": 1,
"percent": 100
},
"lines": {
"count": 22,
"covered": 16,
"percent": 72.72727272727273
},
"regions": {
"count": 17,
"covered": 13,
"notcovered": 4,
"percent": 76.47058823529412
}
}
}
],
"totals": {
"functions": {
"count": 1,
"covered": 1,
"percent": 100
},
"instantiations": {
"count": 1,
"covered": 1,
"percent": 100
},
"lines": {
"count": 22,
"covered": 16,
"percent": 72.72727272727273
},
"regions": {
"count": 17,
"covered": 13,
"notcovered": 4,
"percent": 76.47058823529412
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/overflow.rs",
"summary": {
"functions": {
"count": 2,
"covered": 2,
"percent": 100
},
"instantiations": {
"count": 2,
"covered": 2,
"percent": 100
},
"lines": {
"count": 21,
"covered": 17,
"percent": 80.95238095238095
},
"regions": {
"count": 14,
"covered": 12,
"notcovered": 2,
"percent": 85.71428571428571
}
}
}
],
"totals": {
"functions": {
"count": 2,
"covered": 2,
"percent": 100
},
"instantiations": {
"count": 2,
"covered": 2,
"percent": 100
},
"lines": {
"count": 21,
"covered": 17,
"percent": 80.95238095238095
},
"regions": {
"count": 14,
"covered": 12,
"notcovered": 2,
"percent": 85.71428571428571
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/panic_unwind.rs",
"summary": {
"functions": {
"count": 2,
"covered": 2,
"percent": 100
},
"instantiations": {
"count": 2,
"covered": 2,
"percent": 100
},
"lines": {
"count": 17,
"covered": 14,
"percent": 82.35294117647058
},
"regions": {
"count": 13,
"covered": 11,
"notcovered": 2,
"percent": 84.61538461538461
}
}
}
],
"totals": {
"functions": {
"count": 2,
"covered": 2,
"percent": 100
},
"instantiations": {
"count": 2,
"covered": 2,
"percent": 100
},
"lines": {
"count": 17,
"covered": 14,
"percent": 82.35294117647058
},
"regions": {
"count": 13,
"covered": 11,
"notcovered": 2,
"percent": 84.61538461538461
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/partial_eq.rs",
"summary": {
"functions": {
"count": 5,
"covered": 5,
"percent": 100
},
"instantiations": {
"count": 8,
"covered": 5,
"percent": 62.5
},
"lines": {
"count": 15,
"covered": 15,
"percent": 100
},
"regions": {
"count": 6,
"covered": 6,
"notcovered": 0,
"percent": 100
}
}
}
],
"totals": {
"functions": {
"count": 5,
"covered": 5,
"percent": 100
},
"instantiations": {
"count": 8,
"covered": 5,
"percent": 62.5
},
"lines": {
"count": 15,
"covered": 15,
"percent": 100
},
"regions": {
"count": 6,
"covered": 6,
"notcovered": 0,
"percent": 100
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/simple_loop.rs",
"summary": {
"functions": {
"count": 1,
"covered": 1,
"percent": 100
},
"instantiations": {
"count": 1,
"covered": 1,
"percent": 100
},
"lines": {
"count": 19,
"covered": 19,
"percent": 100
},
"regions": {
"count": 9,
"covered": 8,
"notcovered": 1,
"percent": 88.88888888888889
}
}
}
],
"totals": {
"functions": {
"count": 1,
"covered": 1,
"percent": 100
},
"instantiations": {
"count": 1,
"covered": 1,
"percent": 100
},
"lines": {
"count": 19,
"covered": 19,
"percent": 100
},
"regions": {
"count": 9,
"covered": 8,
"notcovered": 1,
"percent": 88.88888888888889
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/simple_match.rs",
"summary": {
"functions": {
"count": 1,
"covered": 1,
"percent": 100
},
"instantiations": {
"count": 1,
"covered": 1,
"percent": 100
},
"lines": {
"count": 24,
"covered": 24,
"percent": 100
},
"regions": {
"count": 15,
"covered": 14,
"notcovered": 1,
"percent": 93.33333333333333
}
}
}
],
"totals": {
"functions": {
"count": 1,
"covered": 1,
"percent": 100
},
"instantiations": {
"count": 1,
"covered": 1,
"percent": 100
},
"lines": {
"count": 24,
"covered": 24,
"percent": 100
},
"regions": {
"count": 15,
"covered": 14,
"notcovered": 1,
"percent": 93.33333333333333
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/tight_inf_loop.rs",
"summary": {
"functions": {
"count": 1,
"covered": 1,
"percent": 100
},
"instantiations": {
"count": 1,
"covered": 1,
"percent": 100
},
"lines": {
"count": 2,
"covered": 2,
"percent": 100
},
"regions": {
"count": 2,
"covered": 2,
"notcovered": 0,
"percent": 100
}
}
}
],
"totals": {
"functions": {
"count": 1,
"covered": 1,
"percent": 100
},
"instantiations": {
"count": 1,
"covered": 1,
"percent": 100
},
"lines": {
"count": 2,
"covered": 2,
"percent": 100
},
"regions": {
"count": 2,
"covered": 2,
"notcovered": 0,
"percent": 100
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/try_error_result.rs",
"summary": {
"functions": {
"count": 2,
"covered": 2,
"percent": 100
},
"instantiations": {
"count": 2,
"covered": 2,
"percent": 100
},
"lines": {
"count": 20,
"covered": 18,
"percent": 90
},
"regions": {
"count": 19,
"covered": 14,
"notcovered": 5,
"percent": 73.68421052631578
}
}
}
],
"totals": {
"functions": {
"count": 2,
"covered": 2,
"percent": 100
},
"instantiations": {
"count": 2,
"covered": 2,
"percent": 100
},
"lines": {
"count": 20,
"covered": 18,
"percent": 90
},
"regions": {
"count": 19,
"covered": 14,
"notcovered": 5,
"percent": 73.68421052631578
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/while.rs",
"summary": {
"functions": {
"count": 1,
"covered": 1,
"percent": 100
},
"instantiations": {
"count": 1,
"covered": 1,
"percent": 100
},
"lines": {
"count": 4,
"covered": 3,
"percent": 75
},
"regions": {
"count": 4,
"covered": 3,
"notcovered": 1,
"percent": 75
}
}
}
],
"totals": {
"functions": {
"count": 1,
"covered": 1,
"percent": 100
},
"instantiations": {
"count": 1,
"covered": 1,
"percent": 100
},
"lines": {
"count": 4,
"covered": 3,
"percent": 75
},
"regions": {
"count": 4,
"covered": 3,
"notcovered": 1,
"percent": 75
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/while_early_ret.rs",
"summary": {
"functions": {
"count": 1,
"covered": 1,
"percent": 100
},
"instantiations": {
"count": 1,
"covered": 1,
"percent": 100
},
"lines": {
"count": 17,
"covered": 15,
"percent": 88.23529411764706
},
"regions": {
"count": 9,
"covered": 7,
"notcovered": 2,
"percent": 77.77777777777779
}
}
}
],
"totals": {
"functions": {
"count": 1,
"covered": 1,
"percent": 100
},
"instantiations": {
"count": 1,
"covered": 1,
"percent": 100
},
"lines": {
"count": 17,
"covered": 15,
"percent": 88.23529411764706
},
"regions": {
"count": 9,
"covered": 7,
"notcovered": 2,
"percent": 77.77777777777779
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,59 +0,0 @@
{
"data": [
{
"files": [
{
"filename": "../coverage/yield.rs",
"summary": {
"functions": {
"count": 3,
"covered": 3,
"percent": 100
},
"instantiations": {
"count": 3,
"covered": 3,
"percent": 100
},
"lines": {
"count": 23,
"covered": 16,
"percent": 69.56521739130434
},
"regions": {
"count": 22,
"covered": 16,
"notcovered": 6,
"percent": 72.72727272727273
}
}
}
],
"totals": {
"functions": {
"count": 3,
"covered": 3,
"percent": 100
},
"instantiations": {
"count": 3,
"covered": 3,
"percent": 100
},
"lines": {
"count": 23,
"covered": 16,
"percent": 69.56521739130434
},
"regions": {
"count": 22,
"covered": 16,
"notcovered": 6,
"percent": 72.72727272727273
}
}
}
],
"type": "llvm.coverage.json.export",
"version": "2.0.1"
}

View file

@ -1,35 +0,0 @@
1| |#![feature(unwind_attributes)]
2| |#![allow(unused_assignments)]
3| |
4| |#[unwind(aborts)]
5| |fn might_abort(should_abort: bool) {
6| 4| if should_abort {
7| 0| println!("aborting...");
8| 0| panic!("panics and aborts");
9| 4| } else {
10| 4| println!("Don't Panic");
11| 4| }
12| 4|}
13| |
14| |fn main() -> Result<(),u8> {
15| 1| let mut countdown = 10;
16| 11| while countdown > 0 {
17| 10| if countdown < 5 {
18| 4| might_abort(false);
19| 6| }
20| 10| countdown -= 1;
21| | }
22| 1| Ok(())
23| 1|}
24| |
25| |// Notes:
26| |// 1. Compare this program and its coverage results to those of the similar tests
27| |// `panic_unwind.rs` and `try_error_result.rs`.
28| |// 2. This test confirms the coverage generated when a program includes `TerminatorKind::Abort`.
29| |// 3. The test does not invoke the abort. By executing to a successful completion, the coverage
30| |// results show where the program did and did not execute.
31| |// 4. If the program actually aborted, the coverage counters would not be saved (which "works as
32| |// intended"). Coverage results would show no executed coverage regions.
33| |// 6. If `should_abort` is `true` and the program aborts, the program exits with a `132` status
34| |// (on Linux at least).

View file

@ -1,34 +0,0 @@
1| |#![allow(unused_assignments)]
2| |// expect-exit-status-101
3| |
4| |fn might_fail_assert(one_plus_one: u32) {
5| 4| println!("does 1 + 1 = {}?", one_plus_one);
6| 4| assert_eq!(1 + 1, one_plus_one, "the argument was wrong");
^1
7| 3|}
8| |
9| |fn main() -> Result<(),u8> {
10| 1| let mut countdown = 10;
11| 10| while countdown > 0 {
12| 10| if countdown == 1 {
13| 0| might_fail_assert(3);
14| 10| } else if countdown < 5 {
15| 3| might_fail_assert(2);
16| 15| }
17| 9| countdown -= 1;
18| | }
19| 0| Ok(())
20| 0|}
21| |
22| |// Notes:
23| |// 1. Compare this program and its coverage results to those of the very similar test
24| |// `panic_unwind.rs`, and similar tests `abort.rs` and `try_error_result.rs`.
25| |// 2. This test confirms the coverage generated when a program passes or fails an `assert!()` or
26| |// related `assert_*!()` macro.
27| |// 3. Notably, the `assert` macros *do not* generate `TerminatorKind::Assert`. The macros produce
28| |// conditional expressions, `TerminatorKind::SwitchInt` branches, and a possible call to
29| |// `begin_panic_fmt()` (that begins a panic unwind, if the assertion test fails).
30| |// 4. `TerminatoKind::Assert` is, however, also present in the MIR generated for this test
31| |// (and in many other coverage tests). The `Assert` terminator is typically generated by the
32| |// Rust compiler to check for runtime failures, such as numeric overflows.

View file

@ -1,66 +0,0 @@
1| |#![allow(unused_assignments)]
2| |
3| |// require-rust-edition-2018
4| |
5| 1|async fn f() -> u8 { 1 }
6| |
7| |async fn foo() -> [bool; 10] { [false; 10] }
8| |
9| |pub async fn g(x: u8) {
10| | match x {
11| | y if f().await == y => (),
12| | _ => (),
13| | }
14| 1|}
15| |
16| |// #78366: check the reference to the binding is recorded even if the binding is not autorefed
17| |
18| |async fn h(x: usize) {
19| | match x {
20| | y if foo().await[y] => (),
21| | _ => (),
22| | }
23| 1|}
24| |
25| 1|async fn i(x: u8) {
26| 1| match x {
27| 1| y if f().await == y + 1 => (),
^0 ^0
28| 1| _ => (),
29| | }
30| 2|}
31| |
32| 1|fn main() {
33| 1| let _ = g(10);
34| 1| let _ = h(9);
35| 1| let mut future = Box::pin(i(8));
36| 1| executor::block_on(future.as_mut());
37| 1|}
38| |
39| |mod executor {
40| | use core::{
41| | future::Future,
42| | pin::Pin,
43| | task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
44| | };
45| |
46| | pub fn block_on<F: Future>(mut future: F) -> F::Output {
47| 1| let mut future = unsafe { Pin::new_unchecked(&mut future) };
48| 1|
49| 1| static VTABLE: RawWakerVTable = RawWakerVTable::new(
50| 1| |_| unimplemented!("clone"),
51| 1| |_| unimplemented!("wake"),
52| 1| |_| unimplemented!("wake_by_ref"),
53| 1| |_| (),
54| 1| );
55| 1| let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
56| 1| let mut context = Context::from_waker(&waker);
57| |
58| | loop {
59| 1| if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
60| 1| break val;
61| | }
62| 0| }
63| 1| }
64| |}

View file

@ -1,94 +0,0 @@
1| |#![allow(unused_assignments, unused_variables)]
2| |
3| 1|fn main() {
4| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
5| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
6| 1| // dependent conditions.
7| 1| let is_true = std::env::args().len() == 1;
8| 1| let is_false = ! is_true;
9| 1|
10| 1| let mut some_string = Some(String::from("the string content"));
11| 1| println!(
12| 1| "The string or alt: {}"
13| 1| ,
14| 1| some_string
15| 1| .
16| 1| unwrap_or_else
17| 1| (
18| 1| ||
19| | {
20| 0| let mut countdown = 0;
21| 0| if is_false {
22| 0| countdown = 10;
23| 0| }
24| 0| "alt string 1".to_owned()
25| 1| }
26| 1| )
27| 1| );
28| 1|
29| 1| some_string = Some(String::from("the string content"));
30| 1| let
31| 1| a
32| 1| =
33| 1| ||
34| | {
35| 0| let mut countdown = 0;
36| 0| if is_false {
37| 0| countdown = 10;
38| 0| }
39| 0| "alt string 2".to_owned()
40| 1| };
41| 1| println!(
42| 1| "The string or alt: {}"
43| 1| ,
44| 1| some_string
45| 1| .
46| 1| unwrap_or_else
47| 1| (
48| 1| a
49| 1| )
50| 1| );
51| 1|
52| 1| some_string = None;
53| 1| println!(
54| 1| "The string or alt: {}"
55| 1| ,
56| 1| some_string
57| 1| .
58| 1| unwrap_or_else
59| 1| (
60| 1| ||
61| | {
62| 1| let mut countdown = 0;
63| 1| if is_false {
64| 0| countdown = 10;
65| 1| }
66| 1| "alt string 3".to_owned()
67| 1| }
68| 1| )
69| 1| );
70| 1|
71| 1| some_string = None;
72| 1| let
73| 1| a
74| 1| =
75| 1| ||
76| | {
77| 1| let mut countdown = 0;
78| 1| if is_false {
79| 0| countdown = 10;
80| 1| }
81| 1| "alt string 4".to_owned()
82| 1| };
83| 1| println!(
84| 1| "The string or alt: {}"
85| 1| ,
86| 1| some_string
87| 1| .
88| 1| unwrap_or_else
89| 1| (
90| 1| a
91| 1| )
92| 1| );
93| 1|}

View file

@ -1,106 +0,0 @@
1| |#![allow(unused_assignments, unused_variables)]
2| |
3| |fn main() {
4| 1| let mut countdown = 0;
5| 1| if true {
6| 1| countdown = 10;
7| 1| }
8| |
9| | const B: u32 = 100;
10| 1| let x = if countdown > 7 {
11| 1| countdown -= 4;
12| 1| B
13| 0| } else if countdown > 2 {
14| 0| if countdown < 1 || countdown > 5 || countdown != 9 {
15| 0| countdown = 0;
16| 0| }
17| 0| countdown -= 5;
18| 0| countdown
19| | } else {
20| 0| return;
21| | };
22| |
23| 1| let mut countdown = 0;
24| 1| if true {
25| 1| countdown = 10;
26| 1| }
27| |
28| 1| if countdown > 7 {
29| 1| countdown -= 4;
30| 1| } else if countdown > 2 {
^0
31| 0| if countdown < 1 || countdown > 5 || countdown != 9 {
32| 0| countdown = 0;
33| 0| }
34| 0| countdown -= 5;
35| | } else {
36| 0| return;
37| | }
38| |
39| 1| if true {
40| | // Demonstrate the difference with `TerminatorKind::Assert` as of 2020-11-15. Assert is no
41| | // longer treated as a `BasicCoverageBlock` terminator, which changed the coverage region,
42| | // for the executed `then` block above, to include the closing brace on line 30. That
43| | // changed the line count, but the coverage code region (for the `else if` condition) is
44| | // still valid.
45| | //
46| | // Note that `if` (then) and `else` blocks include the closing brace in their coverage
47| | // code regions when the last line in the block ends in a semicolon, because the Rust
48| | // compiler inserts a `StatementKind::Assign` to assign `const ()` to a `Place`, for the
49| | // empty value for the executed block. When the last line does not end in a semicolon
50| | // (that is, when the block actually results in a value), the additional `Assign` is not
51| | // generated, and the brace is not included.
52| 1| let mut countdown = 0;
53| 1| if true {
54| 1| countdown = 10;
55| 1| }
56| |
57| 1| if countdown > 7 {
58| 1| countdown -= 4;
59| 1| }
60| | // The closing brace of the `then` branch is now included in the coverage region, and shown
61| | // as "executed" (giving its line a count of 1 here). Since, in the original version above,
62| | // the closing brace shares the same line as the `else if` conditional expression (which is
63| | // not executed if the first `then` condition is true), only the condition's code region is
64| | // marked with a count of 0 now.
65| 0| else if countdown > 2 {
66| 0| if countdown < 1 || countdown > 5 || countdown != 9 {
67| 0| countdown = 0;
68| 0| }
69| 0| countdown -= 5;
70| | } else {
71| 0| return;
72| | }
73| 1| }
74| |
75| 1| let mut countdown = 0;
76| 1| if true {
77| 1| countdown = 1;
78| 1| }
79| |
80| 1| let z = if countdown > 7 {
^0
81| 0| countdown -= 4;
82| 1| } else if countdown > 2 {
83| 0| if countdown < 1 || countdown > 5 || countdown != 9 {
84| 0| countdown = 0;
85| 0| }
86| 0| countdown -= 5;
87| | } else {
88| 1| let should_be_reachable = countdown;
89| 1| println!("reached");
90| 1| return;
91| | };
92| |
93| 0| let w = if countdown > 7 {
94| 0| countdown -= 4;
95| 0| } else if countdown > 2 {
96| 0| if countdown < 1 || countdown > 5 || countdown != 9 {
97| 0| countdown = 0;
98| 0| }
99| 0| countdown -= 5;
100| | } else {
101| 0| return;
102| | };
103| 1|}

View file

@ -1,34 +0,0 @@
1| |#![allow(unused_assignments)]
2| |// expect-exit-status-1
3| |
4| |struct Firework {
5| | strength: i32,
6| |}
7| |
8| |impl Drop for Firework {
9| 2| fn drop(&mut self) {
10| 2| println!("BOOM times {}!!!", self.strength);
11| 2| }
12| |}
13| |
14| |fn main() -> Result<(),u8> {
15| 1| let _firecracker = Firework { strength: 1 };
16| 1|
17| 1| let _tnt = Firework { strength: 100 };
18| |
19| 1| if true {
20| 1| println!("Exiting with error...");
21| 1| return Err(1);
22| | }
23| |
24| | let _ = Firework { strength: 1000 };
25| |
26| | Ok(())
27| 1|}
28| |
29| |// Expected program output:
30| |// Exiting with error...
31| |// BOOM times 100!!!
32| |// BOOM times 1!!!
33| |// Error: 1

View file

@ -1,67 +0,0 @@
1| |#![allow(unused_assignments)]
2| |// expect-exit-status-1
3| |
4| |struct Firework<T> where T: Copy + std::fmt::Display {
5| | strength: T,
6| |}
7| |
8| |impl<T> Firework<T> where T: Copy + std::fmt::Display {
9| | #[inline(always)]
10| 3| fn set_strength(&mut self, new_strength: T) {
11| 3| self.strength = new_strength;
12| 3| }
------------------
| <generics::Firework<f64>>::set_strength:
| 10| 2| fn set_strength(&mut self, new_strength: T) {
| 11| 2| self.strength = new_strength;
| 12| 2| }
------------------
| <generics::Firework<i32>>::set_strength:
| 10| 1| fn set_strength(&mut self, new_strength: T) {
| 11| 1| self.strength = new_strength;
| 12| 1| }
------------------
13| |}
14| |
15| |impl<T> Drop for Firework<T> where T: Copy + std::fmt::Display {
16| | #[inline(always)]
17| 2| fn drop(&mut self) {
18| 2| println!("BOOM times {}!!!", self.strength);
19| 2| }
------------------
| <generics::Firework<i32> as core::ops::drop::Drop>::drop:
| 17| 1| fn drop(&mut self) {
| 18| 1| println!("BOOM times {}!!!", self.strength);
| 19| 1| }
------------------
| <generics::Firework<f64> as core::ops::drop::Drop>::drop:
| 17| 1| fn drop(&mut self) {
| 18| 1| println!("BOOM times {}!!!", self.strength);
| 19| 1| }
------------------
20| |}
21| |
22| |fn main() -> Result<(),u8> {
23| 1| let mut firecracker = Firework { strength: 1 };
24| 1| firecracker.set_strength(2);
25| 1|
26| 1| let mut tnt = Firework { strength: 100.1 };
27| 1| tnt.set_strength(200.1);
28| 1| tnt.set_strength(300.3);
29| |
30| 1| if true {
31| 1| println!("Exiting with error...");
32| 1| return Err(1);
33| | }
34| |
35| | let _ = Firework { strength: 1000 };
36| |
37| | Ok(())
38| 1|}
39| |
40| |// Expected program output:
41| |// Exiting with error...
42| |// BOOM times 100!!!
43| |// BOOM times 1!!!
44| |// Error: 1

View file

@ -1,30 +0,0 @@
1| |#![allow(unused_assignments, unused_variables)]
2| |
3| |fn main() {
4| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
5| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
6| | // dependent conditions.
7| | let
8| 1| is_true
9| 1| =
10| 1| std::env::args().len()
11| 1| ==
12| 1| 1
13| 1| ;
14| 1| let
15| 1| mut
16| 1| countdown
17| 1| =
18| 1| 0
19| | ;
20| | if
21| 1| is_true
22| 1| {
23| 1| countdown
24| 1| =
25| 1| 10
26| 1| ;
27| 1| }
^0
28| 1|}

View file

@ -1,41 +0,0 @@
1| |#![allow(unused_assignments)]
2| |
3| |fn main() {
4| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
5| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
6| | // dependent conditions.
7| 1| let is_true = std::env::args().len() == 1;
8| 1|
9| 1| let mut countdown = 0;
10| 1| if
11| 1| is_true
12| 1| {
13| 1| countdown
14| 1| =
15| 1| 10
16| 1| ;
17| 1| }
18| | else // Note coverage region difference without semicolon
19| | {
20| 0| countdown
21| 0| =
22| 0| 100
23| | }
24| |
25| | if
26| 1| is_true
27| 1| {
28| 1| countdown
29| 1| =
30| 1| 10
31| 1| ;
32| 1| }
33| | else
34| 0| {
35| 0| countdown
36| 0| =
37| 0| 100
38| 0| ;
39| 0| }
40| 1|}

View file

@ -1,60 +0,0 @@
1| |#![allow(unused_assignments, unused_variables)]
2| |
3| |fn main() {
4| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
5| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
6| | // dependent conditions.
7| 1| let is_true = std::env::args().len() == 1;
8| 1|
9| 1| let mut countdown = 0;
10| 1| if is_true {
11| 1| countdown = 10;
12| 1| }
^0
13| |
14| | mod in_mod {
15| | const IN_MOD_CONST: u32 = 1000;
16| | }
17| |
18| | fn in_func(a: u32) {
19| 3| let b = 1;
20| 3| let c = a + b;
21| 3| println!("c = {}", c)
22| 3| }
23| |
24| | struct InStruct {
25| | in_struct_field: u32,
26| | }
27| |
28| | const IN_CONST: u32 = 1234;
29| |
30| | trait InTrait {
31| | fn trait_func(&mut self, incr: u32);
32| |
33| 1| fn default_trait_func(&mut self) {
34| 1| in_func(IN_CONST);
35| 1| self.trait_func(IN_CONST);
36| 1| }
37| | }
38| |
39| | impl InTrait for InStruct {
40| 1| fn trait_func(&mut self, incr: u32) {
41| 1| self.in_struct_field += incr;
42| 1| in_func(self.in_struct_field);
43| 1| }
44| | }
45| |
46| | type InType = String;
47| |
48| 1| if is_true {
49| 1| in_func(countdown);
50| 1| }
^0
51| |
52| 1| let mut val = InStruct {
53| 1| in_struct_field: 101,
54| 1| };
55| 1|
56| 1| val.default_trait_func();
57| 1|}

View file

@ -1,65 +0,0 @@
1| |#![allow(unused_assignments, unused_variables)]
2| |
3| |fn main() {
4| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
5| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
6| | // dependent conditions.
7| 1| let is_true = std::env::args().len() == 1;
8| 1|
9| 1| let (mut a, mut b, mut c) = (0, 0, 0);
10| 1| if is_true {
11| 1| a = 1;
12| 1| b = 10;
13| 1| c = 100;
14| 1| }
^0
15| | let
16| 1| somebool
17| | =
18| 1| a < b
19| | ||
20| 1| b < c
^0
21| | ;
22| | let
23| 1| somebool
24| | =
25| 1| b < a
26| | ||
27| 1| b < c
28| | ;
29| 1| let somebool = a < b && b < c;
30| 1| let somebool = b < a && b < c;
^0
31| |
32| | if
33| 1| !
34| 1| is_true
35| 0| {
36| 0| a = 2
37| 0| ;
38| 1| }
39| |
40| | if
41| 1| is_true
42| 1| {
43| 1| b = 30
44| 1| ;
45| 1| }
46| | else
47| 0| {
48| 0| c = 400
49| 0| ;
50| 0| }
51| |
52| 1| if !is_true {
53| 0| a = 2;
54| 1| }
55| |
56| 1| if is_true {
57| 1| b = 30;
58| 1| } else {
59| 0| c = 400;
60| 0| }
61| 1|}

View file

@ -1,14 +0,0 @@
1| |#![allow(unused_assignments)]
2| |
3| 1|fn main() {
4| 1| let result
5| 1| =
6| 1| loop
7| 1| {
8| 1| break
9| 1| 10
10| 1| ;
11| 1| }
12| 1| ;
13| 1|}

View file

@ -1,38 +0,0 @@
1| |#![allow(unused_assignments)]
2| |
3| |// This test confirms an earlier problem was resolved, supporting the MIR graph generated by the
4| |// structure of this `fmt` function.
5| |
6| |struct DebugTest;
7| |
8| |impl std::fmt::Debug for DebugTest {
9| | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
10| 1| if true {
11| 1| if false {
12| | while true {
13| | }
14| 1| }
15| 1| write!(f, "error")?;
^0
16| | } else {
17| 1| }
18| 1| Ok(())
19| 1| }
20| |}
21| |
22| 1|fn main() {
23| 1| let debug_test = DebugTest;
24| 1| println!("{:?}", debug_test);
25| 1|}
26| |
27| |/*
28| |
29| |This is the error message generated, before the issue was fixed:
30| |
31| |error: internal compiler error: compiler/rustc_mir/src/transform/coverage/mod.rs:374:42:
32| |Error processing: DefId(0:6 ~ bug_incomplete_cov_graph_traversal_simplified[317d]::{impl#0}::fmt):
33| |Error { message: "`TraverseCoverageGraphWithLoops` missed some `BasicCoverageBlock`s:
34| |[bcb6, bcb7, bcb9]" }
35| |
36| |*/

View file

@ -1,26 +0,0 @@
1| |fn main() {
2| 1| let is_true = std::env::args().len() == 1;
3| 1| let mut countdown = 10;
4| |
5| 1| 'outer: while countdown > 0 {
6| 1| let mut a = 100;
7| 1| let mut b = 100;
8| 3| for _ in 0..50 {
9| 3| if a < 30 {
10| 0| break;
11| | }
12| 3| a -= 5;
13| 3| b -= 5;
14| 3| if b < 90 {
15| 1| a -= 10;
16| 1| if is_true {
17| 1| break 'outer;
18| 0| } else {
19| 0| a -= 2;
20| 0| }
21| 2| }
22| 2| }
23| 0| countdown -= 1;
24| 0| }
25| 1|}

View file

@ -1,64 +0,0 @@
1| |#![allow(unused_assignments)]
2| |// expect-exit-status-101
3| |
4| |fn might_overflow(to_add: u32) -> u32 {
5| 4| if to_add > 5 {
6| 1| println!("this will probably overflow");
7| 3| }
8| 4| let add_to = u32::MAX - 5;
9| 4| println!("does {} + {} overflow?", add_to, to_add);
10| 4| let result = to_add + add_to;
11| 4| println!("continuing after overflow check");
12| 4| result
13| 4|}
14| |
15| |fn main() -> Result<(),u8> {
16| 1| let mut countdown = 10;
17| 10| while countdown > 0 {
18| 10| if countdown == 1 {
19| 0| let result = might_overflow(10);
20| 0| println!("Result: {}", result);
21| 10| } else if countdown < 5 {
22| 3| let result = might_overflow(1);
23| 3| println!("Result: {}", result);
24| 15| }
25| 9| countdown -= 1;
26| | }
27| 0| Ok(())
28| 0|}
29| |
30| |// Notes:
31| |// 1. Compare this program and its coverage results to those of the very similar test `assert.rs`,
32| |// and similar tests `panic_unwind.rs`, abort.rs` and `try_error_result.rs`.
33| |// 2. This test confirms the coverage generated when a program passes or fails a
34| |// compiler-generated `TerminatorKind::Assert` (based on an overflow check, in this case).
35| |// 3. Similar to how the coverage instrumentation handles `TerminatorKind::Call`,
36| |// compiler-generated assertion failures are assumed to be a symptom of a program bug, not
37| |// expected behavior. To simplify the coverage graphs and keep instrumented programs as
38| |// small and fast as possible, `Assert` terminators are assumed to always succeed, and
39| |// therefore are considered "non-branching" terminators. So, an `Assert` terminator does not
40| |// get its own coverage counter.
41| |// 4. After an unhandled panic or failed Assert, coverage results may not always be intuitive.
42| |// In this test, the final count for the statements after the `if` block in `might_overflow()`
43| |// is 4, even though the lines after `to_add + add_to` were executed only 3 times. Depending
44| |// on the MIR graph and the structure of the code, this count could have been 3 (which might
45| |// have been valid for the overflowed add `+`, but should have been 4 for the lines before
46| |// the overflow. The reason for this potential uncertainty is, a `CounterKind` is incremented
47| |// via StatementKind::Counter at the end of the block, but (as in the case in this test),
48| |// a CounterKind::Expression is always evaluated. In this case, the expression was based on
49| |// a `Counter` incremented as part of the evaluation of the `if` expression, which was
50| |// executed, and counted, 4 times, before reaching the overflow add.
51| |
52| |// If the program did not overflow, the coverage for `might_overflow()` would look like this:
53| |//
54| |// 4| |fn might_overflow(to_add: u32) -> u32 {
55| |// 5| 4| if to_add > 5 {
56| |// 6| 0| println!("this will probably overflow");
57| |// 7| 4| }
58| |// 8| 4| let add_to = u32::MAX - 5;
59| |// 9| 4| println!("does {} + {} overflow?", add_to, to_add);
60| |// 10| 4| let result = to_add + add_to;
61| |// 11| 4| println!("continuing after overflow check");
62| |// 12| 4| result
63| |// 13| 4|}

View file

@ -1,50 +0,0 @@
1| |#![allow(unused_assignments)]
2| |// expect-exit-status-101
3| |
4| |fn might_panic(should_panic: bool) {
5| 4| if should_panic {
6| 1| println!("panicking...");
7| 1| panic!("panics");
8| 3| } else {
9| 3| println!("Don't Panic");
10| 3| }
11| 3|}
12| |
13| |fn main() -> Result<(),u8> {
14| 1| let mut countdown = 10;
15| 10| while countdown > 0 {
16| 10| if countdown == 1 {
17| 0| might_panic(true);
18| 10| } else if countdown < 5 {
19| 3| might_panic(false);
20| 15| }
21| 9| countdown -= 1;
22| | }
23| 0| Ok(())
24| 0|}
25| |
26| |// Notes:
27| |// 1. Compare this program and its coverage results to those of the similar tests `abort.rs` and
28| |// `try_error_result.rs`.
29| |// 2. Since the `panic_unwind.rs` test is allowed to unwind, it is also allowed to execute the
30| |// normal program exit cleanup, including writing out the current values of the coverage
31| |// counters.
32| |// 3. The coverage results show (interestingly) that the `panic!()` call did execute, but it does
33| |// not show coverage of the `if countdown == 1` branch in `main()` that calls
34| |// `might_panic(true)` (causing the call to `panic!()`).
35| |// 4. The reason `main()`s `if countdown == 1` branch, calling `might_panic(true)`, appears
36| |// "uncovered" is, InstrumentCoverage (intentionally) treats `TerminatorKind::Call` terminators
37| |// as non-branching, because when a program executes normally, they always are. Errors handled
38| |// via the try `?` operator produce error handling branches that *are* treated as branches in
39| |// coverage results. By treating calls without try `?` operators as non-branching (assumed to
40| |// return normally and continue) the coverage graph can be simplified, producing smaller,
41| |// faster binaries, and cleaner coverage results.
42| |// 5. The reason the coverage results actually show `panic!()` was called is most likely because
43| |// `panic!()` is a macro, not a simple function call, and there are other `Statement`s and/or
44| |// `Terminator`s that execute with a coverage counter before the panic and unwind occur.
45| |// 6. By best practice, programs should not panic. By design, the coverage implementation will not
46| |// incur additional cost (in program size and execution time) to improve coverage results for
47| |// an event that is not supposted to happen.
48| |// 7. FIXME(#78544): This issue describes a feature request for a proposed option to enable
49| |// more accurate coverage results for tests that intentionally panic.

View file

@ -1,111 +0,0 @@
1| |// This test confirms an earlier problem was resolved, supporting the MIR graph generated by the
2| |// structure of this test.
3| |
4| 2|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
^1 ^1
------------------
| Unexecuted instantiation: <partial_eq::Version as core::cmp::PartialOrd>::gt
------------------
| Unexecuted instantiation: <partial_eq::Version as core::cmp::PartialOrd>::le
------------------
| Unexecuted instantiation: <partial_eq::Version as core::cmp::PartialOrd>::ge
------------------
| <partial_eq::Version as core::cmp::PartialOrd>::lt:
| 4| 1|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
------------------
5| |pub struct Version {
6| | major: usize,
7| 1| minor: usize,
8| | patch: usize,
9| |}
10| |
11| |impl Version {
12| | pub fn new(major: usize, minor: usize, patch: usize) -> Self {
13| 2| Self {
14| 2| major,
15| 2| minor,
16| 2| patch,
17| 2| }
18| 2| }
19| |}
20| |
21| 1|fn main() {
22| 1| let version_3_2_1 = Version::new(3, 2, 1);
23| 1| let version_3_3_0 = Version::new(3, 3, 0);
24| 1|
25| 1| println!("{:?} < {:?} = {}", version_3_2_1, version_3_3_0, version_3_2_1 < version_3_3_0);
26| 1|}
27| |
28| |/*
29| |
30| |This test verifies a bug was fixed that otherwise generated this error:
31| |
32| |thread 'rustc' panicked at 'No counters provided the source_hash for function:
33| | Instance {
34| | def: Item(WithOptConstParam {
35| | did: DefId(0:101 ~ autocfg[c44a]::version::{impl#2}::partial_cmp),
36| | const_param_did: None
37| | }),
38| | substs: []
39| | }'
40| |The `PartialOrd` derived by `Version` happened to generate a MIR that generated coverage
41| |without a code region associated with any `Counter`. Code regions were associated with at least
42| |one expression, which is allowed, but the `function_source_hash` was only passed to the codegen
43| |(coverage mapgen) phase from a `Counter`s code region. A new method was added to pass the
44| |`function_source_hash` without a code region, if necessary.
45| |
46| |*/
47| |
48| |// FIXME(richkadel): It may be worth investigating why the coverage report for this test produces
49| |// the following results:
50| |
51| |/*
52| |
53| |1. Why are their two counts below different characters (first and last) of `PartialOrd`, on line 17?
54| |
55| |2. Line 17 is counted twice, but the `::lt` instance shows a line count of 1? Is there a missing
56| | line count with a different instance? Or was it really only called once?
57| |
58| |3. Line 20 shows another line count (of 1) for a line within a `struct` declaration (on only one of
59| | its 3 fields). I doubt the specific field (`minor`) is relevant, but rather I suspect there's a
60| | problem computing the file position here, for some reason.
61| |
62| |<snip>
63| | 16| |
64| | 17| 2|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
65| | ^1 ^1
66| |------------------
67| ||Unexecuted instantiation: <partial_eq_counter_without_region::Version as core::cmp::PartialOrd>::gt
68| |------------------
69| ||Unexecuted instantiation: <partial_eq_counter_without_region::Version as core::cmp::PartialOrd>::le
70| |------------------
71| ||Unexecuted instantiation: <partial_eq_counter_without_region::Version as core::cmp::PartialOrd>::ge
72| |------------------
73| ||<partial_eq_counter_without_region::Version as core::cmp::PartialOrd>::lt:
74| || 17| 1|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
75| |------------------
76| | 18| |pub struct Version {
77| | 19| | major: usize,
78| | 20| 1| minor: usize,
79| | 21| | patch: usize,
80| | 22| |}
81| | 23| |
82| | 24| |impl Version {
83| | 25| | pub fn new(major: usize, minor: usize, patch: usize) -> Self {
84| | 26| 2| Version {
85| | 27| 2| major,
86| | 28| 2| minor,
87| | 29| 2| patch,
88| | 30| 2| }
89| | 31| 2| }
90| | 32| |}
91| | 33| |
92| | 34| 1|fn main() {
93| | 35| 1| let version_3_2_1 = Version::new(3, 2, 1);
94| | 36| 1| let version_3_3_0 = Version::new(3, 3, 0);
95| | 37| 1|
96| | 38| 1| println!("{:?} < {:?} = {}", version_3_2_1, version_3_3_0, version_3_2_1 < version
97| |_3_3_0);
98| | 39| 1|}
99| |*/

View file

@ -1,37 +0,0 @@
1| |#![allow(unused_assignments)]
2| |
3| |fn main() {
4| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
5| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
6| | // dependent conditions.
7| 1| let is_true = std::env::args().len() == 1;
8| 1|
9| 1| let mut countdown = 0;
10| |
11| | if
12| 1| is_true
13| 1| {
14| 1| countdown
15| 1| =
16| 1| 10
17| 1| ;
18| 1| }
^0
19| |
20| | loop
21| | {
22| | if
23| 11| countdown
24| 11| ==
25| 11| 0
26| | {
27| 1| break
28| | ;
29| | }
30| 10| countdown
31| 10| -=
32| 10| 1
33| | ;
34| 1| }
35| 1|}

View file

@ -1,46 +0,0 @@
1| |#![allow(unused_assignments)]
2| |
3| |fn main() {
4| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
5| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
6| | // dependent conditions.
7| 1| let is_true = std::env::args().len() == 1;
8| 1|
9| 1| let mut countdown = 1;
10| 1| if is_true {
11| 1| countdown = 0;
12| 1| }
^0
13| |
14| | for
15| 2| _
16| | in
17| 3| 0..2
18| | {
19| | let z
20| | ;
21| | match
22| 2| countdown
23| | {
24| 1| x
25| | if
26| 2| x
27| 2| <
28| 2| 1
^1
29| | =>
30| 1| {
31| 1| z = countdown
32| 1| ;
33| 1| let y = countdown
34| 1| ;
35| 1| countdown = 10
36| 1| ;
37| 1| }
38| | _
39| | =>
40| 1| {}
41| | }
42| 3| }
43| 1|}

View file

@ -1,6 +0,0 @@
1| |fn main() {
2| 1| if false {
3| | loop {}
4| | }
5| 1|}

View file

@ -1,38 +0,0 @@
1| |#![allow(unused_assignments)]
2| |// expect-exit-status-1
3| |
4| |fn call(return_error: bool) -> Result<(),()> {
5| 6| if return_error {
6| 1| Err(())
7| | } else {
8| 5| Ok(())
9| | }
10| 6|}
11| |
12| |fn main() -> Result<(),()> {
13| 1| let mut
14| 1| countdown = 10
15| | ;
16| | for
17| 6| _
18| | in
19| 6| 0..10
20| | {
21| 6| countdown
22| 6| -= 1
23| 6| ;
24| 6| if
25| 6| countdown < 5
26| | {
27| 1| call(/*return_error=*/ true)?;
28| 0| call(/*return_error=*/ false)?;
29| | }
30| | else
31| | {
32| 5| call(/*return_error=*/ false)?;
^0
33| 5| }
34| 5| }
35| 0| Ok(())
36| 1|}

View file

@ -1,6 +0,0 @@
1| |fn main() {
2| 1| let num = 9;
3| 1| while num >= 10 {
4| 0| }
5| 1|}

View file

@ -1,48 +0,0 @@
1| |#![allow(unused_assignments)]
2| |// expect-exit-status-1
3| |
4| |fn main() -> Result<(),u8> {
5| 1| let mut countdown = 10;
6| | while
7| 7| countdown
8| 7| >
9| 7| 0
10| | {
11| | if
12| 7| countdown
13| 7| <
14| 7| 5
15| | {
16| | return
17| | if
18| 1| countdown
19| 1| >
20| 1| 8
21| | {
22| 0| Ok(())
23| | }
24| | else
25| | {
26| 1| Err(1)
27| | }
28| | ;
29| | }
30| 6| countdown
31| 6| -=
32| 6| 1
33| | ;
34| | }
35| 0| Ok(())
36| 1|}
37| |
38| |// ISSUE(77553): Originally, this test had `Err(1)` on line 22 (instead of `Ok(())`) and
39| |// `std::process::exit(2)` on line 26 (instead of `Err(1)`); and this worked as expected on Linux
40| |// and MacOS. But on Windows (MSVC, at least), the call to `std::process::exit()` exits the program
41| |// without saving the InstrProf coverage counters. The use of `std::process:exit()` is not critical
42| |// to the coverage test for early returns, but this is a limitation that should be fixed.
43| |//
44| |// FIXME(richkadel): Consider creating a new tests for coverage when calling `std::process::exit()`,
45| |// move the `ISSUE` comment to that test, and implement a new test directive that supports skipping
46| |// coverage tests when targeting specific platforms (at least skipping Windows, or MSVC if the
47| |// problem exists on MSVC only).

View file

@ -1,38 +0,0 @@
1| |#![feature(generators, generator_trait)]
2| |#![allow(unused_assignments)]
3| |
4| |use std::ops::{Generator, GeneratorState};
5| |use std::pin::Pin;
6| |
7| |fn main() {
8| 1| let mut generator = || {
9| 1| yield 1;
10| 1| return "foo"
11| 1| };
12| |
13| 1| match Pin::new(&mut generator).resume(()) {
14| 1| GeneratorState::Yielded(1) => {}
15| 0| _ => panic!("unexpected value from resume"),
16| | }
17| 1| match Pin::new(&mut generator).resume(()) {
18| 1| GeneratorState::Complete("foo") => {}
19| 0| _ => panic!("unexpected value from resume"),
20| | }
21| |
22| 1| let mut generator = || {
23| 1| yield 1;
24| 1| yield 2;
25| 0| yield 3;
26| 0| return "foo"
27| 0| };
28| |
29| 1| match Pin::new(&mut generator).resume(()) {
30| 1| GeneratorState::Yielded(1) => {}
31| 0| _ => panic!("unexpected value from resume"),
32| | }
33| 1| match Pin::new(&mut generator).resume(()) {
34| 1| GeneratorState::Yielded(2) => {}
35| 0| _ => panic!("unexpected value from resume"),
36| | }
37| 1|}

View file

@ -1,41 +0,0 @@
Counter in file 0 15:9 -> 15:27, #1
Counter in file 0 16:11 -> 16:24, (#1 + (#2 + #3))
Counter in file 0 17:12 -> 17:25, ((#1 + (#2 + #3)) - #4)
Counter in file 0 17:26 -> 19:10, #2
Counter in file 0 19:10 -> 19:11, #3
Counter in file 0 20:9 -> 20:23, (#2 + #3)
Counter in file 0 22:5 -> 23:2, #4
Counter in file 0 6:8 -> 6:20, #1
Counter in file 0 7:9 -> 8:37, #2
Counter in file 0 9:12 -> 12:2, (#1 - #2)
Emitting segments for file: ../coverage/abort.rs
Combined regions:
6:8 -> 6:20 (count=4)
7:9 -> 8:37 (count=0)
9:12 -> 12:2 (count=4)
15:9 -> 15:27 (count=1)
16:11 -> 16:24 (count=11)
17:12 -> 17:25 (count=10)
17:26 -> 19:10 (count=4)
19:10 -> 19:11 (count=6)
20:9 -> 20:23 (count=10)
22:5 -> 23:2 (count=1)
Segment at 6:8 (count = 4), RegionEntry
Segment at 6:20 (count = 0), Skipped
Segment at 7:9 (count = 0), RegionEntry
Segment at 8:37 (count = 0), Skipped
Segment at 9:12 (count = 4), RegionEntry
Segment at 12:2 (count = 0), Skipped
Segment at 15:9 (count = 1), RegionEntry
Segment at 15:27 (count = 0), Skipped
Segment at 16:11 (count = 11), RegionEntry
Segment at 16:24 (count = 0), Skipped
Segment at 17:12 (count = 10), RegionEntry
Segment at 17:25 (count = 0), Skipped
Segment at 17:26 (count = 4), RegionEntry
Segment at 19:10 (count = 6), RegionEntry
Segment at 19:11 (count = 0), Skipped
Segment at 20:9 (count = 10), RegionEntry
Segment at 20:23 (count = 0), Skipped
Segment at 22:5 (count = 1), RegionEntry
Segment at 23:2 (count = 0), Skipped

View file

@ -1,54 +0,0 @@
Counter in file 0 10:9 -> 10:27, #1
Counter in file 0 11:11 -> 11:24, (#1 + (#2 + (#3 + #4)))
Counter in file 0 12:12 -> 12:26, ((#1 + (#2 + (#3 + #4))) - #5)
Counter in file 0 12:27 -> 14:10, #2
Counter in file 0 14:19 -> 14:32, (((#1 + (#2 + (#3 + #4))) - #5) - #2)
Counter in file 0 14:33 -> 16:10, #3
Counter in file 0 16:10 -> 16:11, #4
Counter in file 0 16:10 -> 16:11, (#3 + #4)
Counter in file 0 17:9 -> 17:23, (#2 + (#3 + #4))
Counter in file 0 19:5 -> 20:2, #5
Counter in file 0 5:5 -> 5:48, #1
Counter in file 0 6:16 -> 6:21, (#1 + 0)
Counter in file 0 6:37 -> 6:61, #2
Counter in file 0 7:1 -> 7:2, (#1 - #2)
Emitting segments for file: ../coverage/assert.rs
Combined regions:
5:5 -> 5:48 (count=4)
6:16 -> 6:21 (count=4)
6:37 -> 6:61 (count=1)
7:1 -> 7:2 (count=3)
10:9 -> 10:27 (count=1)
11:11 -> 11:24 (count=10)
12:12 -> 12:26 (count=10)
12:27 -> 14:10 (count=0)
14:19 -> 14:32 (count=10)
14:33 -> 16:10 (count=3)
16:10 -> 16:11 (count=15)
17:9 -> 17:23 (count=9)
19:5 -> 20:2 (count=0)
Segment at 5:5 (count = 4), RegionEntry
Segment at 5:48 (count = 0), Skipped
Segment at 6:16 (count = 4), RegionEntry
Segment at 6:21 (count = 0), Skipped
Segment at 6:37 (count = 1), RegionEntry
Segment at 6:61 (count = 0), Skipped
Segment at 7:1 (count = 3), RegionEntry
Segment at 7:2 (count = 0), Skipped
Segment at 10:9 (count = 1), RegionEntry
Segment at 10:27 (count = 0), Skipped
Segment at 11:11 (count = 10), RegionEntry
Segment at 11:24 (count = 0), Skipped
Segment at 12:12 (count = 10), RegionEntry
Segment at 12:26 (count = 0), Skipped
Segment at 12:27 (count = 0), RegionEntry
Segment at 14:10 (count = 0), Skipped
Segment at 14:19 (count = 10), RegionEntry
Segment at 14:32 (count = 0), Skipped
Segment at 14:33 (count = 3), RegionEntry
Segment at 16:10 (count = 15), RegionEntry
Segment at 16:11 (count = 0), Skipped
Segment at 17:9 (count = 9), RegionEntry
Segment at 17:23 (count = 0), Skipped
Segment at 19:5 (count = 0), RegionEntry
Segment at 20:2 (count = 0), Skipped

View file

@ -1,85 +0,0 @@
Counter in file 0 15:9 -> 15:75, #1
Counter in file 0 15:9 -> 15:75, #1
Counter in file 0 15:9 -> 15:75, #1
Counter in file 0 47:13 -> 56:54, #1
Counter in file 0 59:32 -> 59:35, ((#1 + #2) - #2)
Counter in file 0 59:39 -> 59:73, (#1 + #2)
Counter in file 0 60:23 -> 60:26, (((#1 + #2) - #2) + 0)
Counter in file 0 62:10 -> 62:11, #2
Counter in file 0 63:5 -> 63:6, (((#1 + #2) - #2) + 0)
Counter in file 0 53:17 -> 53:19, #1
Counter in file 0 7:44 -> 7:45, #1
Counter in file 0 5:24 -> 5:25, #1
Counter in file 0 5:22 -> 5:25, #1
Counter in file 0 25:19 -> 26:12, #1
Counter in file 0 27:9 -> 27:10, #3
Counter in file 0 27:14 -> 27:17, (#1 + 0)
Counter in file 0 27:27 -> 27:32, #2
Counter in file 0 27:32 -> 27:33, (#2 - #3)
Counter in file 0 27:36 -> 27:38, (#3 + 0)
Counter in file 0 28:14 -> 28:16, #4
Counter in file 0 30:1 -> 30:2, (#3 + #4)
Counter in file 0 32:11 -> 37:2, #1
Counter in file 0 30:1 -> 30:2, #1
Counter in file 0 14:1 -> 14:2, #1
Counter in file 0 23:1 -> 23:2, #1
Emitting segments for file: ../coverage/async.rs
Combined regions:
5:22 -> 5:25 (count=1)
5:24 -> 5:25 (count=1)
14:1 -> 14:2 (count=1)
23:1 -> 23:2 (count=1)
25:19 -> 26:12 (count=1)
27:9 -> 27:10 (count=0)
27:14 -> 27:17 (count=1)
27:27 -> 27:32 (count=1)
27:32 -> 27:33 (count=1)
27:36 -> 27:38 (count=0)
28:14 -> 28:16 (count=1)
30:1 -> 30:2 (count=2)
32:11 -> 37:2 (count=1)
47:13 -> 56:54 (count=1)
53:17 -> 53:19 (count=1)
59:32 -> 59:35 (count=1)
59:39 -> 59:73 (count=1)
60:23 -> 60:26 (count=1)
62:10 -> 62:11 (count=0)
63:5 -> 63:6 (count=1)
Segment at 5:22 (count = 1), RegionEntry
Segment at 5:24 (count = 1), RegionEntry
Segment at 5:25 (count = 0), Skipped
Segment at 14:1 (count = 1), RegionEntry
Segment at 14:2 (count = 0), Skipped
Segment at 23:1 (count = 1), RegionEntry
Segment at 23:2 (count = 0), Skipped
Segment at 25:19 (count = 1), RegionEntry
Segment at 26:12 (count = 0), Skipped
Segment at 27:9 (count = 0), RegionEntry
Segment at 27:10 (count = 0), Skipped
Segment at 27:14 (count = 1), RegionEntry
Segment at 27:17 (count = 0), Skipped
Segment at 27:27 (count = 1), RegionEntry
Segment at 27:32 (count = 1), RegionEntry
Segment at 27:33 (count = 0), Skipped
Segment at 27:36 (count = 0), RegionEntry
Segment at 27:38 (count = 0), Skipped
Segment at 28:14 (count = 1), RegionEntry
Segment at 28:16 (count = 0), Skipped
Segment at 30:1 (count = 2), RegionEntry
Segment at 30:2 (count = 0), Skipped
Segment at 32:11 (count = 1), RegionEntry
Segment at 37:2 (count = 0), Skipped
Segment at 47:13 (count = 1), RegionEntry
Segment at 53:17 (count = 1), RegionEntry
Segment at 53:19 (count = 1)
Segment at 56:54 (count = 0), Skipped
Segment at 59:32 (count = 1), RegionEntry
Segment at 59:35 (count = 0), Skipped
Segment at 59:39 (count = 1), RegionEntry
Segment at 59:73 (count = 0), Skipped
Segment at 60:23 (count = 1), RegionEntry
Segment at 60:26 (count = 0), Skipped
Segment at 62:10 (count = 0), RegionEntry
Segment at 62:11 (count = 0), Skipped
Segment at 63:5 (count = 1), RegionEntry
Segment at 63:6 (count = 0), Skipped

View file

@ -1,94 +0,0 @@
Counter in file 0 20:21 -> 20:38, #1
Counter in file 0 21:20 -> 21:28, (#1 + 0)
Counter in file 0 21:29 -> 23:18, #2
Counter in file 0 23:18 -> 23:19, (#1 - #2)
Counter in file 0 24:17 -> 25:14, (#2 + (#1 - #2))
Counter in file 0 3:11 -> 18:13, #1
Counter in file 0 25:14 -> 33:9, (#1 + 0)
Counter in file 0 40:6 -> 60:13, (#1 + 0)
Counter in file 0 67:14 -> 75:9, (#1 + 0)
Counter in file 0 82:6 -> 93:2, (#1 + 0)
Counter in file 0 77:13 -> 77:30, #1
Counter in file 0 78:12 -> 78:20, (#1 + 0)
Counter in file 0 78:21 -> 80:10, #2
Counter in file 0 80:10 -> 80:11, (#1 - #2)
Counter in file 0 81:9 -> 82:6, (#2 + (#1 - #2))
Counter in file 0 62:21 -> 62:38, #1
Counter in file 0 63:20 -> 63:28, (#1 + 0)
Counter in file 0 63:29 -> 65:18, #2
Counter in file 0 65:18 -> 65:19, (#1 - #2)
Counter in file 0 66:17 -> 67:14, (#2 + (#1 - #2))
Counter in file 0 35:13 -> 35:30, #1
Counter in file 0 36:12 -> 36:20, (#1 + 0)
Counter in file 0 36:21 -> 38:10, #2
Counter in file 0 38:10 -> 38:11, (#1 - #2)
Counter in file 0 39:9 -> 40:6, (#2 + (#1 - #2))
Emitting segments for file: ../coverage/closure.rs
Combined regions:
3:11 -> 18:13 (count=1)
20:21 -> 20:38 (count=0)
21:20 -> 21:28 (count=0)
21:29 -> 23:18 (count=0)
23:18 -> 23:19 (count=0)
24:17 -> 25:14 (count=0)
25:14 -> 33:9 (count=1)
35:13 -> 35:30 (count=0)
36:12 -> 36:20 (count=0)
36:21 -> 38:10 (count=0)
38:10 -> 38:11 (count=0)
39:9 -> 40:6 (count=0)
40:6 -> 60:13 (count=1)
62:21 -> 62:38 (count=1)
63:20 -> 63:28 (count=1)
63:29 -> 65:18 (count=0)
65:18 -> 65:19 (count=1)
66:17 -> 67:14 (count=1)
67:14 -> 75:9 (count=1)
77:13 -> 77:30 (count=1)
78:12 -> 78:20 (count=1)
78:21 -> 80:10 (count=0)
80:10 -> 80:11 (count=1)
81:9 -> 82:6 (count=1)
82:6 -> 93:2 (count=1)
Segment at 3:11 (count = 1), RegionEntry
Segment at 18:13 (count = 0), Skipped
Segment at 20:21 (count = 0), RegionEntry
Segment at 20:38 (count = 0), Skipped
Segment at 21:20 (count = 0), RegionEntry
Segment at 21:28 (count = 0), Skipped
Segment at 21:29 (count = 0), RegionEntry
Segment at 23:18 (count = 0), RegionEntry
Segment at 23:19 (count = 0), Skipped
Segment at 24:17 (count = 0), RegionEntry
Segment at 25:14 (count = 1), RegionEntry
Segment at 33:9 (count = 0), Skipped
Segment at 35:13 (count = 0), RegionEntry
Segment at 35:30 (count = 0), Skipped
Segment at 36:12 (count = 0), RegionEntry
Segment at 36:20 (count = 0), Skipped
Segment at 36:21 (count = 0), RegionEntry
Segment at 38:10 (count = 0), RegionEntry
Segment at 38:11 (count = 0), Skipped
Segment at 39:9 (count = 0), RegionEntry
Segment at 40:6 (count = 1), RegionEntry
Segment at 60:13 (count = 0), Skipped
Segment at 62:21 (count = 1), RegionEntry
Segment at 62:38 (count = 0), Skipped
Segment at 63:20 (count = 1), RegionEntry
Segment at 63:28 (count = 0), Skipped
Segment at 63:29 (count = 0), RegionEntry
Segment at 65:18 (count = 1), RegionEntry
Segment at 65:19 (count = 0), Skipped
Segment at 66:17 (count = 1), RegionEntry
Segment at 67:14 (count = 1), RegionEntry
Segment at 75:9 (count = 0), Skipped
Segment at 77:13 (count = 1), RegionEntry
Segment at 77:30 (count = 0), Skipped
Segment at 78:12 (count = 1), RegionEntry
Segment at 78:20 (count = 0), Skipped
Segment at 78:21 (count = 0), RegionEntry
Segment at 80:10 (count = 1), RegionEntry
Segment at 80:11 (count = 0), Skipped
Segment at 81:9 (count = 1), RegionEntry
Segment at 82:6 (count = 1), RegionEntry
Segment at 93:2 (count = 0), Skipped

View file

@ -1,304 +0,0 @@
Counter in file 0 4:9 -> 4:26, #1
Counter in file 0 5:8 -> 5:12, (#1 + 0)
Counter in file 0 5:13 -> 7:6, #2
Counter in file 0 10:9 -> 10:10, (#3 + (#12 + #13))
Counter in file 0 10:16 -> 10:29, (#2 + 0)
Counter in file 0 11:9 -> 12:10, #3
Counter in file 0 13:15 -> 13:28, ((#2 + 0) - #3)
Counter in file 0 14:12 -> 14:25, #4
Counter in file 0 14:29 -> 14:42, (#4 - #15)
Counter in file 0 14:42 -> 14:43, ((#4 - #15) - #16)
Counter in file 0 14:42 -> 14:43, (#15 + #16)
Counter in file 0 14:46 -> 14:60, #23
Counter in file 0 14:60 -> 14:61, (#18 + #19)
Counter in file 0 14:60 -> 14:61, (#23 - #19)
Counter in file 0 14:61 -> 16:10, #12
Counter in file 0 16:10 -> 16:11, #13
Counter in file 0 17:9 -> 18:18, (#12 + #13)
Counter in file 0 20:9 -> 20:15, (((#2 + 0) - #3) - #4)
Counter in file 0 23:9 -> 23:26, ((#3 + (#12 + #13)) + 0)
Counter in file 0 24:8 -> 24:12, ((#3 + (#12 + #13)) + 0)
Counter in file 0 24:13 -> 26:6, #14
Counter in file 0 28:8 -> 28:21, (#14 + 0)
Counter in file 0 28:22 -> 30:6, #17
Counter in file 0 30:15 -> 30:28, ((#14 + 0) - #17)
Counter in file 0 31:12 -> 31:25, (((#14 + 0) - #17) - #8)
Counter in file 0 31:29 -> 31:42, ((((#14 + 0) - #17) - #8) - #24)
Counter in file 0 31:42 -> 31:43, (((((#14 + 0) - #17) - #8) - #24) - #25)
Counter in file 0 31:42 -> 31:43, (#24 + #25)
Counter in file 0 31:46 -> 31:60, #34
Counter in file 0 31:60 -> 31:61, (#34 - #32)
Counter in file 0 31:60 -> 31:61, (#31 + #32)
Counter in file 0 31:61 -> 33:10, #20
Counter in file 0 33:10 -> 33:11, #21
Counter in file 0 34:9 -> 34:23, (#20 + #21)
Counter in file 0 36:9 -> 36:15, #8
Counter in file 0 39:8 -> 39:12, (#17 + (#20 + #21))
Counter in file 0 52:13 -> 52:30, #22
Counter in file 0 53:12 -> 53:16, (#22 + 0)
Counter in file 0 53:17 -> 55:10, #26
Counter in file 0 57:12 -> 57:25, (#26 + 0)
Counter in file 0 57:26 -> 59:10, #27
Counter in file 0 65:17 -> 65:30, ((#26 + 0) - #27)
Counter in file 0 66:16 -> 66:29, (((#26 + 0) - #27) - #7)
Counter in file 0 66:33 -> 66:46, ((((#26 + 0) - #27) - #7) - #37)
Counter in file 0 66:46 -> 66:47, (#37 + #38)
Counter in file 0 66:46 -> 66:47, (((((#26 + 0) - #27) - #7) - #37) - #38)
Counter in file 0 66:50 -> 66:64, #47
Counter in file 0 66:64 -> 66:65, (#47 - #42)
Counter in file 0 66:64 -> 66:65, (#41 + #42)
Counter in file 0 66:65 -> 68:14, #28
Counter in file 0 68:14 -> 68:15, #29
Counter in file 0 69:13 -> 69:27, (#28 + #29)
Counter in file 0 71:13 -> 71:19, #7
Counter in file 0 73:6 -> 73:7, (#27 + (#28 + #29))
Counter in file 0 75:9 -> 75:26, ((#27 + (#28 + #29)) + 0)
Counter in file 0 76:8 -> 76:12, (((#27 + (#28 + #29)) + 0) + 0)
Counter in file 0 76:13 -> 78:6, #30
Counter in file 0 80:9 -> 80:10, (#33 + (#35 + #36))
Counter in file 0 80:16 -> 80:29, (#30 + 0)
Counter in file 0 80:30 -> 82:6, #33
Counter in file 0 82:15 -> 82:28, ((#30 + 0) - #33)
Counter in file 0 83:12 -> 83:25, (((#30 + 0) - #33) - #6)
Counter in file 0 83:29 -> 83:42, ((((#30 + 0) - #33) - #6) - #39)
Counter in file 0 83:42 -> 83:43, (#39 + #40)
Counter in file 0 83:42 -> 83:43, (((((#30 + 0) - #33) - #6) - #39) - #40)
Counter in file 0 83:46 -> 83:60, #48
Counter in file 0 83:60 -> 83:61, (#43 + #44)
Counter in file 0 83:60 -> 83:61, (#48 - #44)
Counter in file 0 83:61 -> 85:10, #35
Counter in file 0 85:10 -> 85:11, #36
Counter in file 0 86:9 -> 86:23, (#35 + #36)
Counter in file 0 88:13 -> 90:15, #6
Counter in file 0 93:9 -> 93:10, (#9 + (#10 + #11))
Counter in file 0 93:16 -> 93:29, ((#33 + (#35 + #36)) + 0)
Counter in file 0 93:30 -> 95:6, #9
Counter in file 0 95:15 -> 95:28, ((#33 + (#35 + #36)) - #9)
Counter in file 0 96:12 -> 96:25, (((#33 + (#35 + #36)) - #9) - #5)
Counter in file 0 96:29 -> 96:42, ((((#33 + (#35 + #36)) - #9) - #5) - #45)
Counter in file 0 96:42 -> 96:43, (#45 + #46)
Counter in file 0 96:42 -> 96:43, (((((#33 + (#35 + #36)) - #9) - #5) - #45) - #46)
Counter in file 0 96:46 -> 96:60, #51
Counter in file 0 96:60 -> 96:61, (#49 + #50)
Counter in file 0 96:60 -> 96:61, (#51 - #50)
Counter in file 0 96:61 -> 98:10, #10
Counter in file 0 98:10 -> 98:11, #11
Counter in file 0 99:9 -> 99:23, (#10 + #11)
Counter in file 0 101:9 -> 101:15, #5
Counter in file 0 103:1 -> 103:2, ((#9 + (#10 + #11)) + (((#5 + #6) + (#7 + #8)) + (((#2 + 0) - #3) - #4)))
Emitting segments for file: ../coverage/conditions.rs
Combined regions:
4:9 -> 4:26 (count=1)
5:8 -> 5:12 (count=1)
5:13 -> 7:6 (count=1)
10:9 -> 10:10 (count=1)
10:16 -> 10:29 (count=1)
11:9 -> 12:10 (count=1)
13:15 -> 13:28 (count=0)
14:12 -> 14:25 (count=0)
14:29 -> 14:42 (count=0)
14:42 -> 14:43 (count=0)
14:46 -> 14:60 (count=0)
14:60 -> 14:61 (count=0)
14:61 -> 16:10 (count=0)
16:10 -> 16:11 (count=0)
17:9 -> 18:18 (count=0)
20:9 -> 20:15 (count=0)
23:9 -> 23:26 (count=1)
24:8 -> 24:12 (count=1)
24:13 -> 26:6 (count=1)
28:8 -> 28:21 (count=1)
28:22 -> 30:6 (count=1)
30:15 -> 30:28 (count=0)
31:12 -> 31:25 (count=0)
31:29 -> 31:42 (count=0)
31:42 -> 31:43 (count=0)
31:46 -> 31:60 (count=0)
31:60 -> 31:61 (count=0)
31:61 -> 33:10 (count=0)
33:10 -> 33:11 (count=0)
34:9 -> 34:23 (count=0)
36:9 -> 36:15 (count=0)
39:8 -> 39:12 (count=1)
52:13 -> 52:30 (count=1)
53:12 -> 53:16 (count=1)
53:17 -> 55:10 (count=1)
57:12 -> 57:25 (count=1)
57:26 -> 59:10 (count=1)
65:17 -> 65:30 (count=0)
66:16 -> 66:29 (count=0)
66:33 -> 66:46 (count=0)
66:46 -> 66:47 (count=0)
66:50 -> 66:64 (count=0)
66:64 -> 66:65 (count=0)
66:65 -> 68:14 (count=0)
68:14 -> 68:15 (count=0)
69:13 -> 69:27 (count=0)
71:13 -> 71:19 (count=0)
73:6 -> 73:7 (count=1)
75:9 -> 75:26 (count=1)
76:8 -> 76:12 (count=1)
76:13 -> 78:6 (count=1)
80:9 -> 80:10 (count=0)
80:16 -> 80:29 (count=1)
80:30 -> 82:6 (count=0)
82:15 -> 82:28 (count=1)
83:12 -> 83:25 (count=0)
83:29 -> 83:42 (count=0)
83:42 -> 83:43 (count=0)
83:46 -> 83:60 (count=0)
83:60 -> 83:61 (count=0)
83:61 -> 85:10 (count=0)
85:10 -> 85:11 (count=0)
86:9 -> 86:23 (count=0)
88:13 -> 90:15 (count=1)
93:9 -> 93:10 (count=0)
93:16 -> 93:29 (count=0)
93:30 -> 95:6 (count=0)
95:15 -> 95:28 (count=0)
96:12 -> 96:25 (count=0)
96:29 -> 96:42 (count=0)
96:42 -> 96:43 (count=0)
96:46 -> 96:60 (count=0)
96:60 -> 96:61 (count=0)
96:61 -> 98:10 (count=0)
98:10 -> 98:11 (count=0)
99:9 -> 99:23 (count=0)
101:9 -> 101:15 (count=0)
103:1 -> 103:2 (count=1)
Segment at 4:9 (count = 1), RegionEntry
Segment at 4:26 (count = 0), Skipped
Segment at 5:8 (count = 1), RegionEntry
Segment at 5:12 (count = 0), Skipped
Segment at 5:13 (count = 1), RegionEntry
Segment at 7:6 (count = 0), Skipped
Segment at 10:9 (count = 1), RegionEntry
Segment at 10:10 (count = 0), Skipped
Segment at 10:16 (count = 1), RegionEntry
Segment at 10:29 (count = 0), Skipped
Segment at 11:9 (count = 1), RegionEntry
Segment at 12:10 (count = 0), Skipped
Segment at 13:15 (count = 0), RegionEntry
Segment at 13:28 (count = 0), Skipped
Segment at 14:12 (count = 0), RegionEntry
Segment at 14:25 (count = 0), Skipped
Segment at 14:29 (count = 0), RegionEntry
Segment at 14:42 (count = 0), RegionEntry
Segment at 14:43 (count = 0), Skipped
Segment at 14:46 (count = 0), RegionEntry
Segment at 14:60 (count = 0), RegionEntry
Segment at 14:61 (count = 0), RegionEntry
Segment at 16:10 (count = 0), RegionEntry
Segment at 16:11 (count = 0), Skipped
Segment at 17:9 (count = 0), RegionEntry
Segment at 18:18 (count = 0), Skipped
Segment at 20:9 (count = 0), RegionEntry
Segment at 20:15 (count = 0), Skipped
Segment at 23:9 (count = 1), RegionEntry
Segment at 23:26 (count = 0), Skipped
Segment at 24:8 (count = 1), RegionEntry
Segment at 24:12 (count = 0), Skipped
Segment at 24:13 (count = 1), RegionEntry
Segment at 26:6 (count = 0), Skipped
Segment at 28:8 (count = 1), RegionEntry
Segment at 28:21 (count = 0), Skipped
Segment at 28:22 (count = 1), RegionEntry
Segment at 30:6 (count = 0), Skipped
Segment at 30:15 (count = 0), RegionEntry
Segment at 30:28 (count = 0), Skipped
Segment at 31:12 (count = 0), RegionEntry
Segment at 31:25 (count = 0), Skipped
Segment at 31:29 (count = 0), RegionEntry
Segment at 31:42 (count = 0), RegionEntry
Segment at 31:43 (count = 0), Skipped
Segment at 31:46 (count = 0), RegionEntry
Segment at 31:60 (count = 0), RegionEntry
Segment at 31:61 (count = 0), RegionEntry
Segment at 33:10 (count = 0), RegionEntry
Segment at 33:11 (count = 0), Skipped
Segment at 34:9 (count = 0), RegionEntry
Segment at 34:23 (count = 0), Skipped
Segment at 36:9 (count = 0), RegionEntry
Segment at 36:15 (count = 0), Skipped
Segment at 39:8 (count = 1), RegionEntry
Segment at 39:12 (count = 0), Skipped
Segment at 52:13 (count = 1), RegionEntry
Segment at 52:30 (count = 0), Skipped
Segment at 53:12 (count = 1), RegionEntry
Segment at 53:16 (count = 0), Skipped
Segment at 53:17 (count = 1), RegionEntry
Segment at 55:10 (count = 0), Skipped
Segment at 57:12 (count = 1), RegionEntry
Segment at 57:25 (count = 0), Skipped
Segment at 57:26 (count = 1), RegionEntry
Segment at 59:10 (count = 0), Skipped
Segment at 65:17 (count = 0), RegionEntry
Segment at 65:30 (count = 0), Skipped
Segment at 66:16 (count = 0), RegionEntry
Segment at 66:29 (count = 0), Skipped
Segment at 66:33 (count = 0), RegionEntry
Segment at 66:46 (count = 0), RegionEntry
Segment at 66:47 (count = 0), Skipped
Segment at 66:50 (count = 0), RegionEntry
Segment at 66:64 (count = 0), RegionEntry
Segment at 66:65 (count = 0), RegionEntry
Segment at 68:14 (count = 0), RegionEntry
Segment at 68:15 (count = 0), Skipped
Segment at 69:13 (count = 0), RegionEntry
Segment at 69:27 (count = 0), Skipped
Segment at 71:13 (count = 0), RegionEntry
Segment at 71:19 (count = 0), Skipped
Segment at 73:6 (count = 1), RegionEntry
Segment at 73:7 (count = 0), Skipped
Segment at 75:9 (count = 1), RegionEntry
Segment at 75:26 (count = 0), Skipped
Segment at 76:8 (count = 1), RegionEntry
Segment at 76:12 (count = 0), Skipped
Segment at 76:13 (count = 1), RegionEntry
Segment at 78:6 (count = 0), Skipped
Segment at 80:9 (count = 0), RegionEntry
Segment at 80:10 (count = 0), Skipped
Segment at 80:16 (count = 1), RegionEntry
Segment at 80:29 (count = 0), Skipped
Segment at 80:30 (count = 0), RegionEntry
Segment at 82:6 (count = 0), Skipped
Segment at 82:15 (count = 1), RegionEntry
Segment at 82:28 (count = 0), Skipped
Segment at 83:12 (count = 0), RegionEntry
Segment at 83:25 (count = 0), Skipped
Segment at 83:29 (count = 0), RegionEntry
Segment at 83:42 (count = 0), RegionEntry
Segment at 83:43 (count = 0), Skipped
Segment at 83:46 (count = 0), RegionEntry
Segment at 83:60 (count = 0), RegionEntry
Segment at 83:61 (count = 0), RegionEntry
Segment at 85:10 (count = 0), RegionEntry
Segment at 85:11 (count = 0), Skipped
Segment at 86:9 (count = 0), RegionEntry
Segment at 86:23 (count = 0), Skipped
Segment at 88:13 (count = 1), RegionEntry
Segment at 90:15 (count = 0), Skipped
Segment at 93:9 (count = 0), RegionEntry
Segment at 93:10 (count = 0), Skipped
Segment at 93:16 (count = 0), RegionEntry
Segment at 93:29 (count = 0), Skipped
Segment at 93:30 (count = 0), RegionEntry
Segment at 95:6 (count = 0), Skipped
Segment at 95:15 (count = 0), RegionEntry
Segment at 95:28 (count = 0), Skipped
Segment at 96:12 (count = 0), RegionEntry
Segment at 96:25 (count = 0), Skipped
Segment at 96:29 (count = 0), RegionEntry
Segment at 96:42 (count = 0), RegionEntry
Segment at 96:43 (count = 0), Skipped
Segment at 96:46 (count = 0), RegionEntry
Segment at 96:60 (count = 0), RegionEntry
Segment at 96:61 (count = 0), RegionEntry
Segment at 98:10 (count = 0), RegionEntry
Segment at 98:11 (count = 0), Skipped
Segment at 99:9 (count = 0), RegionEntry
Segment at 99:23 (count = 0), Skipped
Segment at 101:9 (count = 0), RegionEntry
Segment at 101:15 (count = 0), Skipped
Segment at 103:1 (count = 1), RegionEntry
Segment at 103:2 (count = 0), Skipped

View file

@ -1,22 +0,0 @@
Counter in file 0 9:24 -> 11:6, #1
Counter in file 0 15:9 -> 17:42, #1
Counter in file 0 19:8 -> 19:12, (#1 + 0)
Counter in file 0 20:9 -> 21:22, #2
Counter in file 0 27:1 -> 27:2, (#2 + 0)
Emitting segments for file: ../coverage/drop_trait.rs
Combined regions:
9:24 -> 11:6 (count=2)
15:9 -> 17:42 (count=1)
19:8 -> 19:12 (count=1)
20:9 -> 21:22 (count=1)
27:1 -> 27:2 (count=1)
Segment at 9:24 (count = 2), RegionEntry
Segment at 11:6 (count = 0), Skipped
Segment at 15:9 (count = 1), RegionEntry
Segment at 17:42 (count = 0), Skipped
Segment at 19:8 (count = 1), RegionEntry
Segment at 19:12 (count = 0), Skipped
Segment at 20:9 (count = 1), RegionEntry
Segment at 21:22 (count = 0), Skipped
Segment at 27:1 (count = 1), RegionEntry
Segment at 27:2 (count = 0), Skipped

View file

@ -1,48 +0,0 @@
Counter in file 0 17:24 -> 19:6, #1
Counter in file 0 17:24 -> 19:6, #1
Counter in file 0 23:9 -> 28:28, #1
Counter in file 0 30:8 -> 30:12, (#1 + 0)
Counter in file 0 31:9 -> 32:22, #2
Counter in file 0 38:1 -> 38:2, (#2 + 0)
Counter in file 0 10:49 -> 12:6, #1
Counter in file 0 10:49 -> 12:6, #1
Emitting segments for file: ../coverage/generics.rs
Combined regions:
10:49 -> 12:6 (count=3)
17:24 -> 19:6 (count=2)
23:9 -> 28:28 (count=1)
30:8 -> 30:12 (count=1)
31:9 -> 32:22 (count=1)
38:1 -> 38:2 (count=1)
Segment at 10:49 (count = 3), RegionEntry
Segment at 12:6 (count = 0), Skipped
Segment at 17:24 (count = 2), RegionEntry
Segment at 19:6 (count = 0), Skipped
Segment at 23:9 (count = 1), RegionEntry
Segment at 28:28 (count = 0), Skipped
Segment at 30:8 (count = 1), RegionEntry
Segment at 30:12 (count = 0), Skipped
Segment at 31:9 (count = 1), RegionEntry
Segment at 32:22 (count = 0), Skipped
Segment at 38:1 (count = 1), RegionEntry
Segment at 38:2 (count = 0), Skipped
Emitting segments for function: _RNvMCs4fqI2P2rA04_8genericsINtB2_8FireworkdE12set_strengthB2_
Combined regions:
10:49 -> 12:6 (count=2)
Segment at 10:49 (count = 2), RegionEntry
Segment at 12:6 (count = 0), Skipped
Emitting segments for function: _RNvMCs4fqI2P2rA04_8genericsINtB2_8FireworklE12set_strengthB2_
Combined regions:
10:49 -> 12:6 (count=1)
Segment at 10:49 (count = 1), RegionEntry
Segment at 12:6 (count = 0), Skipped
Emitting segments for function: _RNvXs_Cs4fqI2P2rA04_8genericsINtB4_8FireworklENtNtNtCs7f2nZg1zwMz_4core3ops4drop4Drop4dropB4_
Combined regions:
17:24 -> 19:6 (count=1)
Segment at 17:24 (count = 1), RegionEntry
Segment at 19:6 (count = 0), Skipped
Emitting segments for function: _RNvXs_Cs4fqI2P2rA04_8genericsINtB4_8FireworkdENtNtNtCs7f2nZg1zwMz_4core3ops4drop4Drop4dropB4_
Combined regions:
17:24 -> 19:6 (count=1)
Segment at 17:24 (count = 1), RegionEntry
Segment at 19:6 (count = 0), Skipped

View file

@ -1,21 +0,0 @@
Counter in file 0 8:5 -> 18:10, #1
Counter in file 0 21:9 -> 21:16, (#1 + 0)
Counter in file 0 22:5 -> 27:6, #2
Counter in file 0 27:6 -> 27:7, (#1 - #2)
Counter in file 0 28:1 -> 28:2, (#2 + (#1 - #2))
Emitting segments for file: ../coverage/if.rs
Combined regions:
8:5 -> 18:10 (count=1)
21:9 -> 21:16 (count=1)
22:5 -> 27:6 (count=1)
27:6 -> 27:7 (count=0)
28:1 -> 28:2 (count=1)
Segment at 8:5 (count = 1), RegionEntry
Segment at 18:10 (count = 0), Skipped
Segment at 21:9 (count = 1), RegionEntry
Segment at 21:16 (count = 0), Skipped
Segment at 22:5 (count = 1), RegionEntry
Segment at 27:6 (count = 0), RegionEntry
Segment at 27:7 (count = 0), Skipped
Segment at 28:1 (count = 1), RegionEntry
Segment at 28:2 (count = 0), Skipped

View file

@ -1,30 +0,0 @@
Counter in file 0 7:9 -> 11:16, #1
Counter in file 0 12:5 -> 17:6, #2
Counter in file 0 20:9 -> 22:16, (#1 - #2)
Counter in file 0 26:9 -> 26:16, (#2 + (#1 - #2))
Counter in file 0 27:5 -> 32:6, #3
Counter in file 0 34:5 -> 39:6, ((#2 + (#1 - #2)) - #3)
Counter in file 0 40:1 -> 40:2, (#3 + ((#2 + (#1 - #2)) - #3))
Emitting segments for file: ../coverage/if_else.rs
Combined regions:
7:9 -> 11:16 (count=1)
12:5 -> 17:6 (count=1)
20:9 -> 22:16 (count=0)
26:9 -> 26:16 (count=1)
27:5 -> 32:6 (count=1)
34:5 -> 39:6 (count=0)
40:1 -> 40:2 (count=1)
Segment at 7:9 (count = 1), RegionEntry
Segment at 11:16 (count = 0), Skipped
Segment at 12:5 (count = 1), RegionEntry
Segment at 17:6 (count = 0), Skipped
Segment at 20:9 (count = 0), RegionEntry
Segment at 22:16 (count = 0), Skipped
Segment at 26:9 (count = 1), RegionEntry
Segment at 26:16 (count = 0), Skipped
Segment at 27:5 (count = 1), RegionEntry
Segment at 32:6 (count = 0), Skipped
Segment at 34:5 (count = 0), RegionEntry
Segment at 39:6 (count = 0), Skipped
Segment at 40:1 (count = 1), RegionEntry
Segment at 40:2 (count = 0), Skipped

View file

@ -1,44 +0,0 @@
Counter in file 0 19:13 -> 22:6, #1
Counter in file 0 7:9 -> 9:26, #1
Counter in file 0 10:8 -> 10:15, (#1 + 0)
Counter in file 0 10:16 -> 12:6, #2
Counter in file 0 12:6 -> 12:7, (#1 - #2)
Counter in file 0 48:8 -> 48:15, (#2 + (#1 - #2))
Counter in file 0 48:16 -> 50:6, #3
Counter in file 0 50:6 -> 50:7, ((#2 + (#1 - #2)) - #3)
Counter in file 0 52:9 -> 57:2, (#3 + ((#2 + (#1 - #2)) - #3))
Counter in file 0 33:42 -> 36:10, #1
Counter in file 0 40:45 -> 43:10, #1
Emitting segments for file: ../coverage/inner_items.rs
Combined regions:
7:9 -> 9:26 (count=1)
10:8 -> 10:15 (count=1)
10:16 -> 12:6 (count=1)
12:6 -> 12:7 (count=0)
19:13 -> 22:6 (count=3)
33:42 -> 36:10 (count=1)
40:45 -> 43:10 (count=1)
48:8 -> 48:15 (count=1)
48:16 -> 50:6 (count=1)
50:6 -> 50:7 (count=0)
52:9 -> 57:2 (count=1)
Segment at 7:9 (count = 1), RegionEntry
Segment at 9:26 (count = 0), Skipped
Segment at 10:8 (count = 1), RegionEntry
Segment at 10:15 (count = 0), Skipped
Segment at 10:16 (count = 1), RegionEntry
Segment at 12:6 (count = 0), RegionEntry
Segment at 12:7 (count = 0), Skipped
Segment at 19:13 (count = 3), RegionEntry
Segment at 22:6 (count = 0), Skipped
Segment at 33:42 (count = 1), RegionEntry
Segment at 36:10 (count = 0), Skipped
Segment at 40:45 (count = 1), RegionEntry
Segment at 43:10 (count = 0), Skipped
Segment at 48:8 (count = 1), RegionEntry
Segment at 48:15 (count = 0), Skipped
Segment at 48:16 (count = 1), RegionEntry
Segment at 50:6 (count = 0), RegionEntry
Segment at 50:7 (count = 0), Skipped
Segment at 52:9 (count = 1), RegionEntry
Segment at 57:2 (count = 0), Skipped

View file

@ -1,131 +0,0 @@
Counter in file 0 7:9 -> 9:42, #1
Counter in file 0 10:8 -> 10:15, (#1 + 0)
Counter in file 0 10:16 -> 14:6, #2
Counter in file 0 14:6 -> 14:7, (#1 - #2)
Counter in file 0 16:9 -> 16:17, ((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4))
Counter in file 0 18:13 -> 18:18, (#2 + (#1 - #2))
Counter in file 0 20:13 -> 20:18, ((#2 + (#1 - #2)) - #3)
Counter in file 0 20:18 -> 20:19, (#3 + #4)
Counter in file 0 20:18 -> 20:19, (((#2 + (#1 - #2)) - #3) - #4)
Counter in file 0 23:9 -> 23:17, ((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6))
Counter in file 0 25:13 -> 25:18, (((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) + 0)
Counter in file 0 27:13 -> 27:18, (((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5)
Counter in file 0 27:18 -> 27:19, (#5 + #6)
Counter in file 0 27:18 -> 27:19, ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)
Counter in file 0 29:9 -> 29:17, ((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8))
Counter in file 0 29:20 -> 29:25, (((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) + 0)
Counter in file 0 29:29 -> 29:34, #7
Counter in file 0 29:34 -> 29:35, ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)
Counter in file 0 29:34 -> 29:35, (#7 - #8)
Counter in file 0 30:9 -> 30:17, ((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10))
Counter in file 0 30:20 -> 30:25, (((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) + 0)
Counter in file 0 30:29 -> 30:34, #9
Counter in file 0 30:34 -> 30:35, ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)
Counter in file 0 30:34 -> 30:35, (#9 - #10)
Counter in file 0 33:9 -> 34:16, (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) + 0)
Counter in file 0 35:5 -> 38:6, #11
Counter in file 0 38:6 -> 38:7, (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11)
Counter in file 0 41:9 -> 41:16, (#11 + (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11))
Counter in file 0 42:5 -> 45:6, #12
Counter in file 0 47:5 -> 50:6, ((#11 + (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11)) - #12)
Counter in file 0 52:8 -> 52:16, (#12 + ((#11 + (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11)) - #12))
Counter in file 0 52:17 -> 54:6, #13
Counter in file 0 54:6 -> 54:7, ((#12 + ((#11 + (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11)) - #12)) - #13)
Counter in file 0 56:8 -> 56:15, (#13 + ((#12 + ((#11 + (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11)) - #12)) - #13))
Counter in file 0 56:16 -> 58:6, #14
Counter in file 0 58:12 -> 60:6, ((#13 + ((#12 + ((#11 + (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11)) - #12)) - #13)) - #14)
Counter in file 0 61:1 -> 61:2, (#14 + ((#13 + ((#12 + ((#11 + (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11)) - #12)) - #13)) - #14))
Emitting segments for file: ../coverage/lazy_boolean.rs
Combined regions:
7:9 -> 9:42 (count=1)
10:8 -> 10:15 (count=1)
10:16 -> 14:6 (count=1)
14:6 -> 14:7 (count=0)
16:9 -> 16:17 (count=1)
18:13 -> 18:18 (count=1)
20:13 -> 20:18 (count=0)
20:18 -> 20:19 (count=1)
23:9 -> 23:17 (count=1)
25:13 -> 25:18 (count=1)
27:13 -> 27:18 (count=1)
27:18 -> 27:19 (count=1)
29:9 -> 29:17 (count=1)
29:20 -> 29:25 (count=1)
29:29 -> 29:34 (count=1)
29:34 -> 29:35 (count=1)
30:9 -> 30:17 (count=1)
30:20 -> 30:25 (count=1)
30:29 -> 30:34 (count=0)
30:34 -> 30:35 (count=1)
33:9 -> 34:16 (count=1)
35:5 -> 38:6 (count=0)
38:6 -> 38:7 (count=1)
41:9 -> 41:16 (count=1)
42:5 -> 45:6 (count=1)
47:5 -> 50:6 (count=0)
52:8 -> 52:16 (count=1)
52:17 -> 54:6 (count=0)
54:6 -> 54:7 (count=1)
56:8 -> 56:15 (count=1)
56:16 -> 58:6 (count=1)
58:12 -> 60:6 (count=0)
61:1 -> 61:2 (count=1)
Segment at 7:9 (count = 1), RegionEntry
Segment at 9:42 (count = 0), Skipped
Segment at 10:8 (count = 1), RegionEntry
Segment at 10:15 (count = 0), Skipped
Segment at 10:16 (count = 1), RegionEntry
Segment at 14:6 (count = 0), RegionEntry
Segment at 14:7 (count = 0), Skipped
Segment at 16:9 (count = 1), RegionEntry
Segment at 16:17 (count = 0), Skipped
Segment at 18:13 (count = 1), RegionEntry
Segment at 18:18 (count = 0), Skipped
Segment at 20:13 (count = 0), RegionEntry
Segment at 20:18 (count = 1), RegionEntry
Segment at 20:19 (count = 0), Skipped
Segment at 23:9 (count = 1), RegionEntry
Segment at 23:17 (count = 0), Skipped
Segment at 25:13 (count = 1), RegionEntry
Segment at 25:18 (count = 0), Skipped
Segment at 27:13 (count = 1), RegionEntry
Segment at 27:18 (count = 1), RegionEntry
Segment at 27:19 (count = 0), Skipped
Segment at 29:9 (count = 1), RegionEntry
Segment at 29:17 (count = 0), Skipped
Segment at 29:20 (count = 1), RegionEntry
Segment at 29:25 (count = 0), Skipped
Segment at 29:29 (count = 1), RegionEntry
Segment at 29:34 (count = 1), RegionEntry
Segment at 29:35 (count = 0), Skipped
Segment at 30:9 (count = 1), RegionEntry
Segment at 30:17 (count = 0), Skipped
Segment at 30:20 (count = 1), RegionEntry
Segment at 30:25 (count = 0), Skipped
Segment at 30:29 (count = 0), RegionEntry
Segment at 30:34 (count = 1), RegionEntry
Segment at 30:35 (count = 0), Skipped
Segment at 33:9 (count = 1), RegionEntry
Segment at 34:16 (count = 0), Skipped
Segment at 35:5 (count = 0), RegionEntry
Segment at 38:6 (count = 1), RegionEntry
Segment at 38:7 (count = 0), Skipped
Segment at 41:9 (count = 1), RegionEntry
Segment at 41:16 (count = 0), Skipped
Segment at 42:5 (count = 1), RegionEntry
Segment at 45:6 (count = 0), Skipped
Segment at 47:5 (count = 0), RegionEntry
Segment at 50:6 (count = 0), Skipped
Segment at 52:8 (count = 1), RegionEntry
Segment at 52:16 (count = 0), Skipped
Segment at 52:17 (count = 0), RegionEntry
Segment at 54:6 (count = 1), RegionEntry
Segment at 54:7 (count = 0), Skipped
Segment at 56:8 (count = 1), RegionEntry
Segment at 56:15 (count = 0), Skipped
Segment at 56:16 (count = 1), RegionEntry
Segment at 58:6 (count = 0), Skipped
Segment at 58:12 (count = 0), RegionEntry
Segment at 60:6 (count = 0), Skipped
Segment at 61:1 (count = 1), RegionEntry
Segment at 61:2 (count = 0), Skipped

View file

@ -1,6 +0,0 @@
Counter in file 0 3:11 -> 13:2, #1
Emitting segments for file: ../coverage/loop_break_value.rs
Combined regions:
3:11 -> 13:2 (count=1)
Segment at 3:11 (count = 1), RegionEntry
Segment at 13:2 (count = 0), Skipped

View file

@ -1,37 +0,0 @@
Counter in file 0 10:12 -> 10:16, #1
Counter in file 0 11:16 -> 11:21, #2
Counter in file 0 14:14 -> 14:15, (#2 - #5)
Counter in file 0 15:13 -> 15:31, (0 + (#2 - #5))
Counter in file 0 15:31 -> 15:32, #4
Counter in file 0 17:10 -> 17:11, #3
Counter in file 0 18:9 -> 18:15, (#3 + 0)
Counter in file 0 19:5 -> 19:6, (#4 + (#3 + 0))
Counter in file 0 22:11 -> 25:2, #1
Emitting segments for file: ../coverage/loops_branches.rs
Combined regions:
10:12 -> 10:16 (count=1)
11:16 -> 11:21 (count=1)
14:14 -> 14:15 (count=1)
15:13 -> 15:31 (count=1)
15:31 -> 15:32 (count=0)
17:10 -> 17:11 (count=1)
18:9 -> 18:15 (count=1)
19:5 -> 19:6 (count=1)
22:11 -> 25:2 (count=1)
Segment at 10:12 (count = 1), RegionEntry
Segment at 10:16 (count = 0), Skipped
Segment at 11:16 (count = 1), RegionEntry
Segment at 11:21 (count = 0), Skipped
Segment at 14:14 (count = 1), RegionEntry
Segment at 14:15 (count = 0), Skipped
Segment at 15:13 (count = 1), RegionEntry
Segment at 15:31 (count = 0), RegionEntry
Segment at 15:32 (count = 0), Skipped
Segment at 17:10 (count = 1), RegionEntry
Segment at 17:11 (count = 0), Skipped
Segment at 18:9 (count = 1), RegionEntry
Segment at 18:15 (count = 0), Skipped
Segment at 19:5 (count = 1), RegionEntry
Segment at 19:6 (count = 0), Skipped
Segment at 22:11 (count = 1), RegionEntry
Segment at 25:2 (count = 0), Skipped

View file

@ -1,69 +0,0 @@
Counter in file 0 2:9 -> 3:27, #1
Counter in file 0 5:19 -> 5:32, (#1 + (#2 + #3))
Counter in file 0 6:13 -> 7:24, ((#1 + (#2 + #3)) - #4)
Counter in file 0 8:13 -> 8:14, ((((#1 + (#2 + #3)) - #4) + (#6 + #7)) - #3)
Counter in file 0 8:18 -> 8:23, (((#1 + (#2 + #3)) - #4) + (#6 + #7))
Counter in file 0 9:16 -> 9:22, (((((#1 + (#2 + #3)) - #4) + (#6 + #7)) - #3) + 0)
Counter in file 0 10:17 -> 10:22, #2
Counter in file 0 12:13 -> 13:19, (((((#1 + (#2 + #3)) - #4) + (#6 + #7)) - #3) - #2)
Counter in file 0 14:16 -> 14:22, ((((((#1 + (#2 + #3)) - #4) + (#6 + #7)) - #3) - #2) + 0)
Counter in file 0 15:17 -> 16:27, ((((((#1 + (#2 + #3)) - #4) + (#6 + #7)) - #3) - #2) - #7)
Counter in file 0 17:21 -> 17:33, #5
Counter in file 0 18:24 -> 21:14, #6
Counter in file 0 21:14 -> 21:15, #7
Counter in file 0 22:10 -> 22:11, (#6 + #7)
Counter in file 0 23:9 -> 23:23, (#2 + #3)
Counter in file 0 24:6 -> 24:7, #4
Counter in file 0 25:1 -> 25:2, (#5 + #4)
Emitting segments for file: ../coverage/nested_loops.rs
Combined regions:
2:9 -> 3:27 (count=1)
5:19 -> 5:32 (count=1)
6:13 -> 7:24 (count=1)
8:13 -> 8:14 (count=3)
8:18 -> 8:23 (count=3)
9:16 -> 9:22 (count=3)
10:17 -> 10:22 (count=0)
12:13 -> 13:19 (count=3)
14:16 -> 14:22 (count=3)
15:17 -> 16:27 (count=1)
17:21 -> 17:33 (count=1)
18:24 -> 21:14 (count=0)
21:14 -> 21:15 (count=2)
22:10 -> 22:11 (count=2)
23:9 -> 23:23 (count=0)
24:6 -> 24:7 (count=0)
25:1 -> 25:2 (count=1)
Segment at 2:9 (count = 1), RegionEntry
Segment at 3:27 (count = 0), Skipped
Segment at 5:19 (count = 1), RegionEntry
Segment at 5:32 (count = 0), Skipped
Segment at 6:13 (count = 1), RegionEntry
Segment at 7:24 (count = 0), Skipped
Segment at 8:13 (count = 3), RegionEntry
Segment at 8:14 (count = 0), Skipped
Segment at 8:18 (count = 3), RegionEntry
Segment at 8:23 (count = 0), Skipped
Segment at 9:16 (count = 3), RegionEntry
Segment at 9:22 (count = 0), Skipped
Segment at 10:17 (count = 0), RegionEntry
Segment at 10:22 (count = 0), Skipped
Segment at 12:13 (count = 3), RegionEntry
Segment at 13:19 (count = 0), Skipped
Segment at 14:16 (count = 3), RegionEntry
Segment at 14:22 (count = 0), Skipped
Segment at 15:17 (count = 1), RegionEntry
Segment at 16:27 (count = 0), Skipped
Segment at 17:21 (count = 1), RegionEntry
Segment at 17:33 (count = 0), Skipped
Segment at 18:24 (count = 0), RegionEntry
Segment at 21:14 (count = 2), RegionEntry
Segment at 21:15 (count = 0), Skipped
Segment at 22:10 (count = 2), RegionEntry
Segment at 22:11 (count = 0), Skipped
Segment at 23:9 (count = 0), RegionEntry
Segment at 23:23 (count = 0), Skipped
Segment at 24:6 (count = 0), RegionEntry
Segment at 24:7 (count = 0), Skipped
Segment at 25:1 (count = 1), RegionEntry
Segment at 25:2 (count = 0), Skipped

View file

@ -1,53 +0,0 @@
Counter in file 0 16:9 -> 16:27, #1
Counter in file 0 17:11 -> 17:24, (#1 + (#2 + (#3 + #4)))
Counter in file 0 18:12 -> 18:26, ((#1 + (#2 + (#3 + #4))) - #5)
Counter in file 0 18:27 -> 21:10, #2
Counter in file 0 21:19 -> 21:32, (((#1 + (#2 + (#3 + #4))) - #5) - #2)
Counter in file 0 21:33 -> 24:10, #3
Counter in file 0 24:10 -> 24:11, #4
Counter in file 0 24:10 -> 24:11, (#3 + #4)
Counter in file 0 25:9 -> 25:23, (#2 + (#3 + #4))
Counter in file 0 27:5 -> 28:2, #5
Counter in file 0 5:8 -> 5:18, #1
Counter in file 0 5:19 -> 7:6, #2
Counter in file 0 7:6 -> 7:7, (#1 - #2)
Counter in file 0 8:9 -> 13:2, (#2 + (#1 - #2))
Emitting segments for file: ../coverage/overflow.rs
Combined regions:
5:8 -> 5:18 (count=4)
5:19 -> 7:6 (count=1)
7:6 -> 7:7 (count=3)
8:9 -> 13:2 (count=4)
16:9 -> 16:27 (count=1)
17:11 -> 17:24 (count=10)
18:12 -> 18:26 (count=10)
18:27 -> 21:10 (count=0)
21:19 -> 21:32 (count=10)
21:33 -> 24:10 (count=3)
24:10 -> 24:11 (count=15)
25:9 -> 25:23 (count=9)
27:5 -> 28:2 (count=0)
Segment at 5:8 (count = 4), RegionEntry
Segment at 5:18 (count = 0), Skipped
Segment at 5:19 (count = 1), RegionEntry
Segment at 7:6 (count = 3), RegionEntry
Segment at 7:7 (count = 0), Skipped
Segment at 8:9 (count = 4), RegionEntry
Segment at 13:2 (count = 0), Skipped
Segment at 16:9 (count = 1), RegionEntry
Segment at 16:27 (count = 0), Skipped
Segment at 17:11 (count = 10), RegionEntry
Segment at 17:24 (count = 0), Skipped
Segment at 18:12 (count = 10), RegionEntry
Segment at 18:26 (count = 0), Skipped
Segment at 18:27 (count = 0), RegionEntry
Segment at 21:10 (count = 0), Skipped
Segment at 21:19 (count = 10), RegionEntry
Segment at 21:32 (count = 0), Skipped
Segment at 21:33 (count = 3), RegionEntry
Segment at 24:10 (count = 15), RegionEntry
Segment at 24:11 (count = 0), Skipped
Segment at 25:9 (count = 9), RegionEntry
Segment at 25:23 (count = 0), Skipped
Segment at 27:5 (count = 0), RegionEntry
Segment at 28:2 (count = 0), Skipped

Some files were not shown because too many files have changed in this diff Show more