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:
parent
f6c9c1a576
commit
def932ca86
354 changed files with 12634 additions and 20486 deletions
|
@ -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);
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 ®ion in tcx.covered_code_regions(def_id) {
|
||||
function_coverage.add_unreachable_region(region.clone());
|
||||
}
|
||||
}
|
||||
if cgu_covered_files.is_empty() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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, _), .. })
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)"),
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 binary’s 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
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>>];
|
||||
}
|
||||
|
|
|
@ -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 -> 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() -> [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() -> [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>];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
- }
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
- }
|
||||
-
|
||||
|
|
|
@ -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.
|
|
@ -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 | \
|
||||
|
|
|
@ -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.
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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).
|
||||
|
|
@ -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.
|
||||
|
|
@ -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| |}
|
||||
|
|
@ -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|}
|
||||
|
|
@ -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|}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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|}
|
||||
|
|
@ -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|}
|
||||
|
|
@ -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|}
|
||||
|
|
@ -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|}
|
||||
|
|
@ -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|}
|
||||
|
|
@ -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| |*/
|
||||
|
|
@ -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|}
|
||||
|
|
@ -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|}
|
||||
|
|
@ -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.
|
||||
|
|
@ -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| |*/
|
||||
|
|
@ -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|}
|
||||
|
|
@ -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|}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
1| |fn main() {
|
||||
2| 1| if false {
|
||||
3| | loop {}
|
||||
4| | }
|
||||
5| 1|}
|
||||
|
|
@ -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|}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
1| |fn main() {
|
||||
2| 1| let num = 9;
|
||||
3| 1| while num >= 10 {
|
||||
4| 0| }
|
||||
5| 1|}
|
||||
|
|
@ -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).
|
||||
|
|
@ -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|}
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
Loading…
Add table
Reference in a new issue