coverage bug fixes and optimization support

Adjusted LLVM codegen for code compiled with `-Zinstrument-coverage` to
address multiple, somewhat related issues.

Fixed a significant flaw in prior coverage solution: Every counter
generated a new counter variable, but there should have only been one
counter variable per function. This appears to have bloated .profraw
files significantly. (For a small program, it increased the size by
about 40%. I have not tested large programs, but there is anecdotal
evidence that profraw files were way too large. This is a good fix,
regardless, but hopefully it also addresses related issues.

Fixes: #82144

Invalid LLVM coverage data produced when compiled with -C opt-level=1

Existing tests now work up to at least `opt-level=3`. This required a
detailed analysis of the LLVM IR, comparisons with Clang C++ LLVM IR
when compiled with coverage, and a lot of trial and error with codegen
adjustments.

The biggest hurdle was figuring out how to continue to support coverage
results for unused functions and generics. Rust's coverage results have
three advantages over Clang's coverage results:

1. Rust's coverage map does not include any overlapping code regions,
   making coverage counting unambiguous.
2. Rust generates coverage results (showing zero counts) for all unused
   functions, including generics. (Clang does not generate coverage for
   uninstantiated template functions.)
3. Rust's unused functions produce minimal stubbed functions in LLVM IR,
   sufficient for including in the coverage results; while Clang must
   generate the complete LLVM IR for each unused function, even though
   it will never be called.

This PR removes the previous hack of attempting to inject coverage into
some other existing function instance, and generates dedicated instances
for each unused function. This change, and a few other adjustments
(similar to what is required for `-C link-dead-code`, but with lower
impact), makes it possible to support LLVM optimizations.

Fixes: #79651

Coverage report: "Unexecuted instantiation:..." for a generic function
from multiple crates

Fixed by removing the aforementioned hack. Some "Unexecuted
instantiation" notices are unavoidable, as explained in the
`used_crate.rs` test, but `-Zinstrument-coverage` has new options to
back off support for either unused generics, or all unused functions,
which avoids the notice, at the cost of less coverage of unused
functions.

Fixes: #82875

Invalid LLVM coverage data produced with crate brotli_decompressor

Fixed by disabling the LLVM function attribute that forces inlining, if
`-Z instrument-coverage` is enabled. This attribute is applied to
Rust functions with `#[inline(always)], and in some cases, the forced
inlining breaks coverage instrumentation and reports.
This commit is contained in:
Rich Kadel 2021-03-15 16:32:45 -07:00
parent cebc8fef5f
commit bcf755562a
62 changed files with 3061 additions and 342 deletions

View file

@ -143,7 +143,7 @@ fn module_codegen(tcx: TyCtxt<'_>, cgu_name: Symbol) -> ModuleCodegen<ModuleLlvm
// Finalize code coverage by injecting the coverage map. Note, the coverage map will
// also be added to the `llvm.used` variable, created next.
if cx.sess().opts.debugging_opts.instrument_coverage {
if cx.sess().instrument_coverage() {
cx.coverageinfo_finalize();
}

View file

@ -79,7 +79,7 @@ pub struct CodegenCx<'ll, 'tcx> {
pub pointee_infos: RefCell<FxHashMap<(Ty<'tcx>, Size), Option<PointeeInfo>>>,
pub isize_ty: &'ll Type,
pub coverage_cx: Option<coverageinfo::CrateCoverageContext<'tcx>>,
pub coverage_cx: Option<coverageinfo::CrateCoverageContext<'ll, 'tcx>>,
pub dbg_cx: Option<debuginfo::CrateDebugContext<'ll, 'tcx>>,
eh_personality: Cell<Option<&'ll Value>>,
@ -280,7 +280,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
let (llcx, llmod) = (&*llvm_module.llcx, llvm_module.llmod());
let coverage_cx = if tcx.sess.opts.debugging_opts.instrument_coverage {
let coverage_cx = if tcx.sess.instrument_coverage() {
let covctx = coverageinfo::CrateCoverageContext::new();
Some(covctx)
} else {
@ -331,7 +331,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
}
#[inline]
pub fn coverage_context(&'a self) -> Option<&'a coverageinfo::CrateCoverageContext<'tcx>> {
pub fn coverage_context(&'a self) -> Option<&'a coverageinfo::CrateCoverageContext<'ll, 'tcx>> {
self.coverage_cx.as_ref()
}
}
@ -712,7 +712,7 @@ macro_rules! mk_struct {
ifn!("llvm.va_end", fn(i8p) -> void);
ifn!("llvm.va_copy", fn(i8p, i8p) -> void);
if self.sess().opts.debugging_opts.instrument_coverage {
if self.sess().instrument_coverage() {
ifn!("llvm.instrprof.increment", fn(i8p, t_i64, t_i32, t_i32) -> void);
}

View file

@ -3,13 +3,12 @@
use crate::llvm;
use llvm::coverageinfo::CounterMappingRegion;
use rustc_codegen_ssa::coverageinfo::map::{Counter, CounterExpression, FunctionCoverage};
use rustc_codegen_ssa::traits::ConstMethods;
use rustc_codegen_ssa::coverageinfo::map::{Counter, CounterExpression};
use rustc_codegen_ssa::traits::{ConstMethods, CoverageInfoMethods};
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;
@ -20,16 +19,17 @@
///
/// This Coverage Map complies with Coverage Mapping Format version 4 (zero-based encoded as 3),
/// as defined at [LLVM Code Coverage Mapping Format](https://github.com/rust-lang/llvm-project/blob/rustc/11.0-2020-10-12/llvm/docs/CoverageMappingFormat.rst#llvm-code-coverage-mapping-format)
/// and published in Rust's current (November 2020) fork of LLVM. This version is supported by the
/// LLVM coverage tools (`llvm-profdata` and `llvm-cov`) bundled with Rust's fork of LLVM.
/// and published in Rust's November 2020 fork of LLVM. This version is supported by the LLVM
/// coverage tools (`llvm-profdata` and `llvm-cov`) bundled with Rust's fork of LLVM.
///
/// Consequently, Rust's bundled version of Clang also generates Coverage Maps compliant with
/// version 3. Clang's implementation of Coverage Map generation was referenced when implementing
/// this Rust version, and though the format documentation is very explicit and detailed, some
/// undocumented details in Clang's implementation (that may or may not be important) were also
/// replicated for Rust's Coverage Map.
/// the same version. Clang's implementation of Coverage Map generation was referenced when
/// implementing this Rust version, and though the format documentation is very explicit and
/// detailed, some 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();
@ -39,17 +39,24 @@ pub fn finalize<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) {
debug!("Generating coverage map for CodegenUnit: `{}`", cx.codegen_unit.name());
let mut function_coverage_map = match cx.coverage_context() {
// In order to show that unused functions have coverage counts of zero (0), LLVM requires the
// functions exist. Generate synthetic functions with a (required) single counter, and add the
// MIR `Coverage` code regions to the `function_coverage_map`, before calling
// `ctx.take_function_coverage_map()`.
if !tcx.sess.instrument_coverage_except_unused_functions() {
add_unused_functions(cx);
}
let function_coverage_map = match cx.coverage_context() {
Some(ctx) => ctx.take_function_coverage_map(),
None => return,
};
if function_coverage_map.is_empty() {
// This module has no functions with coverage instrumentation
return;
}
add_unreachable_coverage(tcx, &mut function_coverage_map);
let mut mapgen = CoverageMapGenerator::new();
// Encode coverage mappings and generate function records
@ -57,7 +64,8 @@ pub fn finalize<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) {
for (instance, function_coverage) in function_coverage_map {
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 source_hash = function_coverage.source_hash();
let is_used = function_coverage.is_used();
let (expressions, counter_regions) =
function_coverage.get_expressions_and_counter_regions();
@ -69,7 +77,7 @@ pub fn finalize<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) {
"Every `FunctionCoverage` should have at least one counter"
);
function_data.push((mangled_function_name, function_source_hash, coverage_mapping_buffer));
function_data.push((mangled_function_name, source_hash, is_used, coverage_mapping_buffer));
}
// Encode all filenames referenced by counters/expressions in this module
@ -84,13 +92,14 @@ pub fn finalize<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) {
// Generate the LLVM IR representation of the coverage map and store it in a well-known global
let cov_data_val = mapgen.generate_coverage_map(cx, version, filenames_size, filenames_val);
for (mangled_function_name, function_source_hash, coverage_mapping_buffer) in function_data {
for (mangled_function_name, source_hash, is_used, coverage_mapping_buffer) in function_data {
save_function_record(
cx,
mangled_function_name,
function_source_hash,
source_hash,
filenames_ref,
coverage_mapping_buffer,
is_used,
);
}
@ -201,9 +210,10 @@ fn generate_coverage_map(
fn save_function_record(
cx: &CodegenCx<'ll, 'tcx>,
mangled_function_name: String,
function_source_hash: u64,
source_hash: u64,
filenames_ref: u64,
coverage_mapping_buffer: Vec<u8>,
is_used: bool,
) {
// Concatenate the encoded coverage mappings
let coverage_mapping_size = coverage_mapping_buffer.len();
@ -212,128 +222,120 @@ fn save_function_record(
let func_name_hash = coverageinfo::hash_str(&mangled_function_name);
let func_name_hash_val = cx.const_u64(func_name_hash);
let coverage_mapping_size_val = cx.const_u32(coverage_mapping_size as u32);
let func_hash_val = cx.const_u64(function_source_hash);
let source_hash_val = cx.const_u64(source_hash);
let filenames_ref_val = cx.const_u64(filenames_ref);
let func_record_val = cx.const_struct(
&[
func_name_hash_val,
coverage_mapping_size_val,
func_hash_val,
source_hash_val,
filenames_ref_val,
coverage_mapping_val,
],
/*packed=*/ true,
);
// At the present time, the coverage map for Rust assumes every instrumented function `is_used`.
// Note that Clang marks functions as "unused" in `CodeGenPGO::emitEmptyCounterMapping`. (See:
// https://github.com/rust-lang/llvm-project/blob/de02a75e398415bad4df27b4547c25b896c8bf3b/clang%2Flib%2FCodeGen%2FCodeGenPGO.cpp#L877-L878
// for example.)
//
// It's not yet clear if or how this may be applied to Rust in the future, but the `is_used`
// argument is available and handled similarly.
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.
/// or "Unreachable", were still parsed and processed through the MIR stage, but were not
/// codegenned. (Note that `-Clink-dead-code` can force some unused code to be codegenned, but
/// that flag is known to cause other errors, when combined with `-Z instrument-coverage`; and
/// `-Clink-dead-code` will not generate code for unused generic functions.)
///
/// We can find the unreachable functions by the set difference of all MIR `DefId`s (`tcx` query
/// `mir_keys`) minus the codegenned `DefId`s (`tcx` query `collect_and_partition_mono_items`).
/// We can find the unused functions (including generic functions) by the set difference 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 generic
/// 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>>,
) {
/// allocated to only one of those CGUs. We must NOT inject any unused functions's `CodeRegion`s
/// more than once, so we have to pick a CGUs `function_coverage_map` into which the unused
/// function will be inserted.
fn add_unused_functions<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) {
let tcx = cx.tcx;
// FIXME(#79622): Can this solution be simplified and/or improved? Are there other sources
// of compiler state data that might help (or better sources that could be exposed, but
// aren't yet)?
// 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 ignore_unused_generics = tcx.sess.instrument_coverage_except_unused_generics();
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 all_def_ids: DefIdSet = tcx
.mir_keys(LOCAL_CRATE)
.iter()
.filter_map(|local_def_id| {
let def_id = local_def_id.to_def_id();
if ignore_unused_generics && tcx.generics_of(def_id).count() > 0 {
return None;
}
Some(local_def_id.to_def_id())
})
.collect();
let codegenned_def_ids = tcx.codegened_and_inlined_items(LOCAL_CRATE);
let mut unreachable_def_ids_by_file: FxHashMap<Symbol, Vec<DefId>> = FxHashMap::default();
let mut unused_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
// Make sure the non-codegenned (unused) 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);
let def_ids =
unused_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)
if unused_def_ids_by_file.is_empty() {
// There are no unused 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:
// Each `CodegenUnit` (CGU) has its own function_coverage_map, and generates a specific binary
// with its own coverage map.
//
// 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).
// Each covered function `Instance` can be included in only one coverage map, produced from a
// specific function_coverage_map, from a specific CGU.
//
// Since unused functions did not generate code, they are not associated with any CGU yet.
//
// To avoid injecting the unused functions in multiple coverage maps (for multiple CGUs)
// determine which function_coverage_map has the responsibility for publishing unreachable
// coverage, based on file name: For each unused function, find the CGU that generates the
// first function (based on sorted `DefId`) from the same file.
//
// Add a new `FunctionCoverage` to the `function_coverage_map`, with unreachable code regions
// for each region in it's MIR.
// Convert the `HashSet` of `codegenned_def_ids` to a sortable vector, and sort 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);
}
if let Some(covered_file_name) = tcx.covered_file_name(def_id) {
// Only add files known to have unused functions
if unused_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 cgu_covered_def_ids: DefIdSet = match cx.coverage_context() {
Some(ctx) => ctx
.function_coverage_map
.borrow()
.keys()
.map(|&instance| instance.def.def_id())
.collect(),
None => return,
};
let mut cgu_covered_files: FxHashSet<Symbol> = first_covered_def_id_by_file
let cgu_covered_files: FxHashSet<Symbol> = first_covered_def_id_by_file
.iter()
.filter_map(
|(&file_name, def_id)| {
@ -342,49 +344,13 @@ fn add_unreachable_coverage<'tcx>(
)
.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()
{
// Note, this loop adds an unreachable code regions for each MIR-derived region.
// Alternatively, we could add a single code region for the maximum span of all
// code regions here.
//
// Observed downsides of this approach are:
//
// 1. The coverage results will appear inconsistent compared with the same (or
// similar) code in a function that is reached.
// 2. If the function is unreachable from one crate but reachable when compiling
// another referencing crate (such as a cross-crate reference to a
// generic function or inlined function), actual coverage regions overlaid
// on a single larger code span of `Zero` coverage can appear confusing or
// wrong. Chaning the unreachable coverage from a `code_region` to a
// `gap_region` can help, but still can look odd with `0` line counts for
// lines between executed (> 0) lines (such as for blank lines or comments).
for &region in tcx.covered_code_regions(def_id) {
function_coverage.add_unreachable_region(region.clone());
}
}
if cgu_covered_files.is_empty() {
break;
}
// For each file for which this CGU is responsible for adding unused function coverage,
// get the `def_id`s for each unused function (if any), define a synthetic function with a
// single LLVM coverage counter, and add the function's coverage `CodeRegion`s. to the
// function_coverage_map.
for covered_file_name in cgu_covered_files {
for def_id in unused_def_ids_by_file.remove(&covered_file_name).into_iter().flatten() {
cx.define_unused_fn(def_id);
}
}
}

View file

@ -1,5 +1,6 @@
use crate::llvm;
use crate::abi::{Abi, FnAbi};
use crate::builder::Builder;
use crate::common::CodegenCx;
@ -7,33 +8,47 @@
use llvm::coverageinfo::CounterMappingRegion;
use rustc_codegen_ssa::coverageinfo::map::{CounterExpression, FunctionCoverage};
use rustc_codegen_ssa::traits::{
BaseTypeMethods, CoverageInfoBuilderMethods, CoverageInfoMethods, MiscMethods, StaticMethods,
BaseTypeMethods, BuilderMethods, ConstMethods, CoverageInfoBuilderMethods, CoverageInfoMethods,
MiscMethods, StaticMethods,
};
use rustc_data_structures::fx::FxHashMap;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_llvm::RustString;
use rustc_middle::bug;
use rustc_middle::mir::coverage::{
CodeRegion, CounterValueReference, ExpressionOperandId, InjectedExpressionId, Op,
};
use rustc_middle::ty;
use rustc_middle::ty::layout::FnAbiExt;
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::Instance;
use std::cell::RefCell;
use std::ffi::CString;
use std::iter;
use tracing::debug;
pub mod mapgen;
const UNUSED_FUNCTION_COUNTER_ID: CounterValueReference = CounterValueReference::START;
const VAR_ALIGN_BYTES: usize = 8;
/// A context object for maintaining all state needed by the coverageinfo module.
pub struct CrateCoverageContext<'tcx> {
pub struct CrateCoverageContext<'ll, 'tcx> {
// Coverage data for each instrumented function identified by DefId.
pub(crate) function_coverage_map: RefCell<FxHashMap<Instance<'tcx>, FunctionCoverage<'tcx>>>,
pub(crate) pgo_func_name_var_map: RefCell<FxHashMap<Instance<'tcx>, &'ll llvm::Value>>,
}
impl<'tcx> CrateCoverageContext<'tcx> {
impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> {
pub fn new() -> Self {
Self { function_coverage_map: Default::default() }
Self {
function_coverage_map: Default::default(),
pgo_func_name_var_map: Default::default(),
}
}
pub fn take_function_coverage_map(&self) -> FxHashMap<Instance<'tcx>, FunctionCoverage<'tcx>> {
@ -41,23 +56,44 @@ pub fn take_function_coverage_map(&self) -> FxHashMap<Instance<'tcx>, FunctionCo
}
}
impl CoverageInfoMethods for CodegenCx<'ll, 'tcx> {
impl CoverageInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn coverageinfo_finalize(&self) {
mapgen::finalize(self)
}
fn get_pgo_func_name_var(&self, instance: Instance<'tcx>) -> &'ll llvm::Value {
if let Some(coverage_context) = self.coverage_context() {
debug!("getting pgo_func_name_var for instance={:?}", instance);
let mut pgo_func_name_var_map = coverage_context.pgo_func_name_var_map.borrow_mut();
pgo_func_name_var_map
.entry(instance)
.or_insert_with(|| self.create_pgo_func_name_var(instance))
} else {
bug!("Could not get the `coverage_context`");
}
}
/// Calls llvm::createPGOFuncNameVar() with the given function instance's
/// mangled function name. The LLVM API returns an llvm::GlobalVariable
/// containing the function name, with the specific variable name and
/// linkage required by LLVM InstrProf source-based coverage
/// instrumentation. Use `bx.get_pgo_func_name_var()` to ensure the variable
/// is only created once per `Instance`.
fn create_pgo_func_name_var(&self, instance: Instance<'tcx>) -> &'ll llvm::Value {
let mangled_fn_name = CString::new(self.tcx.symbol_name(instance).name)
.expect("error converting function name to C string");
let llfn = self.get_fn(instance);
unsafe { llvm::LLVMRustCoverageCreatePGOFuncNameVar(llfn, mangled_fn_name.as_ptr()) }
}
fn define_unused_fn(&self, def_id: DefId) {
let instance = declare_unused_fn(self, &def_id);
codegen_unused_fn_and_counter(self, instance);
add_function_coverage(self, instance, def_id);
}
}
impl CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
/// Calls llvm::createPGOFuncNameVar() with the given function instance's mangled function name.
/// The LLVM API returns an llvm::GlobalVariable containing the function name, with the specific
/// variable name and linkage required by LLVM InstrProf source-based coverage instrumentation.
fn create_pgo_func_name_var(&self, instance: Instance<'tcx>) -> Self::Value {
let llfn = self.cx.get_fn(instance);
let mangled_fn_name = CString::new(self.tcx.symbol_name(instance).name)
.expect("error converting function name to C string");
unsafe { llvm::LLVMRustCoverageCreatePGOFuncNameVar(llfn, mangled_fn_name.as_ptr()) }
}
fn set_function_source_hash(
&mut self,
instance: Instance<'tcx>,
@ -145,6 +181,86 @@ fn add_coverage_unreachable(&mut self, instance: Instance<'tcx>, region: CodeReg
}
}
fn declare_unused_fn(cx: &CodegenCx<'ll, 'tcx>, def_id: &DefId) -> Instance<'tcx> {
let tcx = cx.tcx;
let instance = Instance::new(
*def_id,
InternalSubsts::for_item(tcx, *def_id, |param, _| {
if let ty::GenericParamDefKind::Lifetime = param.kind {
tcx.lifetimes.re_erased.into()
} else {
tcx.mk_param_from_def(param)
}
}),
);
let llfn = cx.declare_fn(
&tcx.symbol_name(instance).name,
&FnAbi::of_fn_ptr(
cx,
ty::Binder::dummy(tcx.mk_fn_sig(
iter::once(tcx.mk_unit()),
tcx.mk_unit(),
false,
hir::Unsafety::Unsafe,
Abi::Rust,
)),
&[],
),
);
unsafe {
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
}
cx.instances.borrow_mut().insert(instance, llfn);
instance
}
fn codegen_unused_fn_and_counter(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) {
let llfn = cx.get_fn(instance);
let mut bx = Builder::new_block(cx, llfn, "unused_function");
let fn_name = bx.get_pgo_func_name_var(instance);
let hash = bx.const_u64(0);
let num_counters = bx.const_u32(1);
let index = bx.const_u32(u32::from(UNUSED_FUNCTION_COUNTER_ID));
debug!(
"codegen intrinsic instrprof.increment(fn_name={:?}, hash={:?}, num_counters={:?},
index={:?}) for unused function: {:?}",
fn_name, hash, num_counters, index, instance
);
bx.instrprof_increment(fn_name, hash, num_counters, index);
bx.ret_void();
}
fn add_function_coverage(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>, def_id: DefId) {
let tcx = cx.tcx;
let mut function_coverage = FunctionCoverage::unused(tcx, instance);
for (index, &code_region) in tcx.covered_code_regions(def_id).iter().enumerate() {
if index == 0 {
// Insert at least one real counter so the LLVM CoverageMappingReader will find expected
// definitions.
function_coverage.add_counter(UNUSED_FUNCTION_COUNTER_ID, code_region.clone());
}
// Add a Zero Counter for every code region.
//
// Even though the first coverage region already has an actual Counter, `llvm-cov` will not
// always report it. Re-adding an unreachable region (zero counter) for the same region
// seems to help produce the expected coverage.
function_coverage.add_unreachable_region(code_region.clone());
}
if let Some(coverage_context) = cx.coverage_context() {
coverage_context.function_coverage_map.borrow_mut().insert(instance, function_coverage);
} else {
bug!("Could not get the `coverage_context`");
}
}
pub(crate) fn write_filenames_section_to_buffer<'a>(
filenames: impl IntoIterator<Item = &'a CString>,
buffer: &RustString,
@ -177,6 +293,7 @@ pub(crate) fn write_mapping_to_buffer(
);
}
}
pub(crate) fn hash_str(strval: &str) -> u64 {
let strval = CString::new(strval).expect("null error converting hashable str to C string");
unsafe { llvm::LLVMRustCoverageHashCString(strval.as_ptr()) }

View file

@ -1746,7 +1746,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
);
// OBJECT-FILES-NO, AUDIT-ORDER
if sess.opts.cg.profile_generate.enabled() || sess.opts.debugging_opts.instrument_coverage {
if sess.opts.cg.profile_generate.enabled() || sess.instrument_coverage() {
cmd.pgo_gen();
}

View file

@ -188,9 +188,7 @@ fn exported_symbols_provider_local(
}
}
if tcx.sess.opts.debugging_opts.instrument_coverage
|| tcx.sess.opts.cg.profile_generate.enabled()
{
if tcx.sess.instrument_coverage() || tcx.sess.opts.cg.profile_generate.enabled() {
// These are weak symbols that point to the profile version and the
// profile name, which need to be treated as exported so LTO doesn't nix
// them.

View file

@ -176,7 +176,7 @@ macro_rules! if_regular {
// The rustc option `-Zinstrument_coverage` injects intrinsic calls to
// `llvm.instrprof.increment()`, which requires the LLVM `instrprof` pass.
if sess.opts.debugging_opts.instrument_coverage {
if sess.instrument_coverage() {
passes.push("instrprof".to_owned());
}
passes

View file

@ -31,27 +31,44 @@ pub struct Expression {
pub struct FunctionCoverage<'tcx> {
instance: Instance<'tcx>,
source_hash: u64,
is_used: bool,
counters: IndexVec<CounterValueReference, Option<CodeRegion>>,
expressions: IndexVec<InjectedExpressionIndex, Option<Expression>>,
unreachable_regions: Vec<CodeRegion>,
}
impl<'tcx> FunctionCoverage<'tcx> {
/// Creates a new set of coverage data for a used (called) function.
pub fn new(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Self {
Self::create(tcx, instance, true)
}
/// Creates a new set of coverage data for an unused (never called) function.
pub fn unused(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Self {
Self::create(tcx, instance, false)
}
fn create(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, is_used: bool) -> Self {
let coverageinfo = tcx.coverageinfo(instance.def_id());
debug!(
"FunctionCoverage::new(instance={:?}) has coverageinfo={:?}",
instance, coverageinfo
"FunctionCoverage::new(instance={:?}) has coverageinfo={:?}. is_used={}",
instance, coverageinfo, is_used
);
Self {
instance,
source_hash: 0, // will be set with the first `add_counter()`
is_used,
counters: IndexVec::from_elem_n(None, coverageinfo.num_counters as usize),
expressions: IndexVec::from_elem_n(None, coverageinfo.num_expressions as usize),
unreachable_regions: Vec::new(),
}
}
/// Returns true for a used (called) function, and false for an unused function.
pub fn is_used(&self) -> bool {
self.is_used
}
/// Sets the function source hash value. If called multiple times for the same function, all
/// calls should have the same hash value.
pub fn set_function_source_hash(&mut self, source_hash: u64) {
@ -128,8 +145,8 @@ pub fn get_expressions_and_counter_regions<'a>(
&'a self,
) -> (Vec<CounterExpression>, impl Iterator<Item = (Counter, &'a CodeRegion)>) {
assert!(
self.source_hash != 0,
"No counters provided the source_hash for function: {:?}",
self.source_hash != 0 || !self.is_used,
"No counters provided the source_hash for used function: {:?}",
self.instance
);

View file

@ -33,7 +33,7 @@ pub fn codegen_coverage(&self, bx: &mut Bx, coverage: Coverage, scope: SourceSco
let coverageinfo = bx.tcx().coverageinfo(instance.def_id());
let fn_name = bx.create_pgo_func_name_var(instance);
let fn_name = bx.get_pgo_func_name_var(instance);
let hash = bx.const_u64(function_source_hash);
let num_counters = bx.const_u32(coverageinfo.num_counters);
let index = bx.const_u32(u32::from(id));

View file

@ -1,14 +1,41 @@
use super::BackendTypes;
use rustc_hir::def_id::DefId;
use rustc_middle::mir::coverage::*;
use rustc_middle::ty::Instance;
pub trait CoverageInfoMethods: BackendTypes {
pub trait CoverageInfoMethods<'tcx>: BackendTypes {
fn coverageinfo_finalize(&self);
/// Functions with MIR-based coverage are normally codegenned _only_ if
/// called. LLVM coverage tools typically expect every function to be
/// defined (even if unused), with at least one call to LLVM intrinsic
/// `instrprof.increment`.
///
/// Codegen a small function that will never be called, with one counter
/// that will never be incremented.
///
/// For used/called functions, the coverageinfo was already added to the
/// `function_coverage_map` (keyed by function `Instance`) during codegen.
/// But in this case, since the unused function was _not_ previously
/// codegenned, collect the coverage `CodeRegion`s from the MIR and add
/// them. The first `CodeRegion` is used to add a single counter, with the
/// same counter ID used in the injected `instrprof.increment` intrinsic
/// call. Since the function is never called, all other `CodeRegion`s can be
/// added as `unreachable_region`s.
fn define_unused_fn(&self, def_id: DefId);
/// For LLVM codegen, returns a function-specific `Value` for a global
/// string, to hold the function name passed to LLVM intrinsic
/// `instrprof.increment()`. The `Value` is only created once per instance.
/// Multiple invocations with the same instance return the same `Value`.
fn get_pgo_func_name_var(&self, instance: Instance<'tcx>) -> Self::Value;
/// Creates a new PGO function name variable. This should only be called
/// to fill in the unused function names array.
fn create_pgo_func_name_var(&self, instance: Instance<'tcx>) -> Self::Value;
}
pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes {
fn create_pgo_func_name_var(&self, instance: Instance<'tcx>) -> Self::Value;
/// Returns true if the function source hash was added to the coverage map (even if it had
/// already been added, for this instance). Returns false *only* if `-Z instrument-coverage` is
/// not enabled (a coverage map is not being generated).

View file

@ -58,7 +58,7 @@ pub trait CodegenMethods<'tcx>:
+ MiscMethods<'tcx>
+ ConstMethods<'tcx>
+ StaticMethods
+ CoverageInfoMethods
+ CoverageInfoMethods<'tcx>
+ DebugInfoMethods<'tcx>
+ AsmMethods
+ PreDefineMethods<'tcx>
@ -74,7 +74,7 @@ impl<'tcx, T> CodegenMethods<'tcx> for T where
+ MiscMethods<'tcx>
+ ConstMethods<'tcx>
+ StaticMethods
+ CoverageInfoMethods
+ CoverageInfoMethods<'tcx>
+ DebugInfoMethods<'tcx>
+ AsmMethods
+ PreDefineMethods<'tcx>

View file

@ -2,6 +2,7 @@
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig};
use rustc_session::config::InstrumentCoverage;
use rustc_session::config::Strip;
use rustc_session::config::{build_configuration, build_session_options, to_crate_config};
use rustc_session::config::{rustc_optgroups, ErrorOutputType, ExternLocation, Options, Passes};
@ -560,7 +561,7 @@ macro_rules! tracked {
tracked!(inline_mir, Some(true));
tracked!(inline_mir_threshold, Some(123));
tracked!(inline_mir_hint_threshold, Some(123));
tracked!(instrument_coverage, true);
tracked!(instrument_coverage, Some(InstrumentCoverage::All));
tracked!(instrument_mcount, true);
tracked!(link_only, true);
tracked!(merge_functions, Some(MergeFunctions::Disabled));

View file

@ -736,7 +736,7 @@ fn inject_panic_runtime(&mut self, krate: &ast::Crate) {
}
fn inject_profiler_runtime(&mut self, krate: &ast::Crate) {
if (self.sess.opts.debugging_opts.instrument_coverage
if (self.sess.instrument_coverage()
|| self.sess.opts.debugging_opts.profile
|| self.sess.opts.cg.profile_generate.enabled())
&& !self.sess.opts.debugging_opts.no_profiler_runtime

View file

@ -1537,9 +1537,10 @@ pub enum StatementKind<'tcx> {
AscribeUserType(Box<(Place<'tcx>, UserTypeProjection)>, ty::Variance),
/// Marks the start of a "coverage region", injected with '-Zinstrument-coverage'. A
/// `CoverageInfo` statement carries metadata about the coverage region, used to inject a coverage
/// map into the binary. The `Counter` kind also generates executable code, to increment a
/// counter varible at runtime, each time the code region is executed.
/// `Coverage` statement carries metadata about the coverage region, used to inject a coverage
/// map into the binary. If `Coverage::kind` is a `Counter`, the statement also generates
/// executable code, to increment a counter varible at runtime, each time the code region is
/// executed.
Coverage(Box<Coverage>),
/// Denotes a call to the intrinsic function copy_overlapping, where `src_dst` denotes the

View file

@ -84,7 +84,14 @@ pub fn instantiation_mode(&self, tcx: TyCtxt<'tcx>) -> InstantiationMode {
.debugging_opts
.inline_in_all_cgus
.unwrap_or_else(|| tcx.sess.opts.optimize != OptLevel::No)
&& !tcx.sess.link_dead_code();
&& !tcx.sess.link_dead_code()
&& !tcx.sess.instrument_coverage();
// Disabled for `-Z instrument-coverage` because some LLVM optimizations can sometimes
// break coverage results. A test that failed at certain optimization levels is now
// validated at that optimization level (via `compile-flags` directive):
// * `src/test/run-make-fulldeps/coverage/closure.rs` broke with `-C opt-level=2`, and
// also required disabling `internalize_symbols` in
// `rustc_mir/monomorphize/partitioning/mod.rs`
match *self {
MonoItem::Fn(ref instance) => {

View file

@ -328,7 +328,10 @@
/// 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) }
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() }
}
@ -336,7 +339,10 @@
/// 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) }
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() }
}

View file

@ -196,7 +196,13 @@ pub fn partition<'tcx>(
// Next we try to make as many symbols "internal" as possible, so LLVM has
// more freedom to optimize.
if !tcx.sess.link_dead_code() {
if !tcx.sess.link_dead_code() && !tcx.sess.instrument_coverage() {
// Disabled for `-Z instrument-coverage` because some LLVM optimizations can sometimes
// break coverage results. Tests that failed at certain optimization levels are now
// validated at those optimization levels (via `compile-flags` directive); for example:
// * `src/test/run-make-fulldeps/coverage/async.rs` broke with `-C opt-level=1`
// * `src/test/run-make-fulldeps/coverage/closure.rs` broke with `-C opt-level=2`, and
// also required disabling `generate_gcu_internal_copies` in `rustc_middle/mir/mono.rs`
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_internalize_symbols");
partitioner.internalize_symbols(cx, &mut post_inlining);
}

View file

@ -6,10 +6,9 @@
use rustc_middle::ty::{self, TyCtxt};
use rustc_span::def_id::DefId;
/// The `query` provider for `CoverageInfo`, requested by `codegen_coverage()` (to inject each
/// counter) and `FunctionCoverage::new()` (to extract the coverage map metadata from the MIR).
/// A `query` provider for retrieving coverage information injected into MIR.
pub(crate) fn provide(providers: &mut Providers) {
providers.coverageinfo = |tcx, def_id| coverageinfo_from_mir(tcx, def_id);
providers.coverageinfo = |tcx, def_id| coverageinfo(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);
}
@ -121,7 +120,7 @@ fn visit_coverage(&mut self, coverage: &Coverage) {
}
}
fn coverageinfo_from_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> CoverageInfo {
fn coverageinfo<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> CoverageInfo {
let mir_body = mir_body(tcx, def_id);
let mut coverage_visitor = CoverageVisitor {
@ -139,29 +138,22 @@ fn coverageinfo_from_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> CoverageInfo
}
fn covered_file_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<Symbol> {
let body = mir_body(tcx, def_id);
for bb_data in 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() {
if is_inlined(body, statement) {
continue;
if tcx.is_mir_available(def_id) {
let body = mir_body(tcx, def_id);
for bb_data in 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() {
if is_inlined(body, statement) {
continue;
}
return Some(code_region.file_name);
}
return Some(code_region.file_name);
}
}
}
}
None
}
/// This function ensures we obtain the correct MIR for the given item irrespective of
/// whether that means const mir or runtime mir. For `const fn` this opts for runtime
/// mir.
fn mir_body<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx mir::Body<'tcx> {
let id = ty::WithOptConstParam::unknown(def_id);
let def = ty::InstanceDef::Item(id);
tcx.instance_mir(def)
return None;
}
fn covered_code_regions<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Vec<&'tcx CodeRegion> {
@ -188,3 +180,12 @@ fn is_inlined(body: &Body<'_>, statement: &Statement<'_>) -> bool {
let scope_data = &body.source_scopes[statement.source_info.scope];
scope_data.inlined.is_some() || scope_data.inlined_parent_scope.is_some()
}
/// This function ensures we obtain the correct MIR for the given item irrespective of
/// whether that means const mir or runtime mir. For `const fn` this opts for runtime
/// mir.
fn mir_body<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx mir::Body<'tcx> {
let id = ty::WithOptConstParam::unknown(def_id);
let def = ty::InstanceDef::Item(id);
tcx.instance_mir(def)
}

View file

@ -313,11 +313,8 @@ fn mir_promoted(
&simplify::SimplifyCfg::new("promote-consts"),
];
let opt_coverage: &[&dyn MirPass<'tcx>] = if tcx.sess.opts.debugging_opts.instrument_coverage {
&[&coverage::InstrumentCoverage]
} else {
&[]
};
let opt_coverage: &[&dyn MirPass<'tcx>] =
if tcx.sess.instrument_coverage() { &[&coverage::InstrumentCoverage] } else { &[] };
run_passes(tcx, &mut body, MirPhase::ConstPromotion, &[promote, opt_coverage]);

View file

@ -184,6 +184,37 @@ pub enum MirSpanview {
Block,
}
/// The different settings that the `-Z instrument-coverage` flag can have.
///
/// Coverage instrumentation now supports combining `-Z instrument-coverage`
/// with compiler and linker optimization (enabled with `-O` or `-C opt-level=1`
/// and higher). Nevertheless, there are many variables, depending on options
/// selected, code structure, and enabled attributes. If errors are encountered,
/// either while compiling or when generating `llvm-cov show` reports, consider
/// lowering the optimization level, including or excluding `-C link-dead-code`,
/// or using `-Z instrument-coverage=except-unused-functions` or `-Z
/// instrument-coverage=except-unused-generics`.
///
/// Note that `ExceptUnusedFunctions` means: When `mapgen.rs` generates the
/// coverage map, it will not attempt to generate synthetic functions for unused
/// (and not code-generated) functions (whether they are generic or not). As a
/// result, non-codegenned functions will not be included in the coverage map,
/// and will not appear, as covered or uncovered, in coverage reports.
///
/// `ExceptUnusedGenerics` will add synthetic functions to the coverage map,
/// unless the function has type parameters.
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum InstrumentCoverage {
/// Default `-Z instrument-coverage` or `-Z instrument-coverage=statement`
All,
/// `-Z instrument-coverage=except-unused-generics`
ExceptUnusedGenerics,
/// `-Z instrument-coverage=except-unused-functions`
ExceptUnusedFunctions,
/// `-Z instrument-coverage=off` (or `no`, etc.)
Off,
}
#[derive(Clone, PartialEq, Hash)]
pub enum LinkerPluginLto {
LinkerPlugin(PathBuf),
@ -1911,7 +1942,9 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
);
}
if debugging_opts.instrument_coverage {
if debugging_opts.instrument_coverage.is_some()
&& debugging_opts.instrument_coverage != Some(InstrumentCoverage::Off)
{
if cg.profile_generate.enabled() || cg.profile_use.is_some() {
early_error(
error_format,
@ -2298,9 +2331,9 @@ pub fn needs_analysis(&self) -> bool {
/// how the hash should be calculated when adding a new command-line argument.
crate mod dep_tracking {
use super::{
CFGuard, CrateType, DebugInfo, ErrorOutputType, LinkerPluginLto, LtoCli, OptLevel,
OutputTypes, Passes, SanitizerSet, SourceFileHashAlgorithm, SwitchWithOptPath,
SymbolManglingVersion, TrimmedDefPaths,
CFGuard, CrateType, DebugInfo, ErrorOutputType, InstrumentCoverage, LinkerPluginLto,
LtoCli, OptLevel, OutputTypes, Passes, SanitizerSet, SourceFileHashAlgorithm,
SwitchWithOptPath, SymbolManglingVersion, TrimmedDefPaths,
};
use crate::lint;
use crate::options::WasiExecModel;
@ -2364,6 +2397,7 @@ fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType) {
impl_dep_tracking_hash_via_hash!(Option<WasiExecModel>);
impl_dep_tracking_hash_via_hash!(Option<PanicStrategy>);
impl_dep_tracking_hash_via_hash!(Option<RelroLevel>);
impl_dep_tracking_hash_via_hash!(Option<InstrumentCoverage>);
impl_dep_tracking_hash_via_hash!(Option<lint::Level>);
impl_dep_tracking_hash_via_hash!(Option<PathBuf>);
impl_dep_tracking_hash_via_hash!(CrateType);

View file

@ -262,6 +262,7 @@ mod $mod_desc {
pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavor::one_of();
pub const parse_optimization_fuel: &str = "crate=integer";
pub const parse_mir_spanview: &str = "`statement` (default), `terminator`, or `block`";
pub const parse_instrument_coverage: &str = "`all` (default), `except-unused-generics`, `except-unused-functions`, or `off`";
pub const parse_unpretty: &str = "`string` or `string=string`";
pub const parse_treat_err_as_bug: &str = "either no value or a number bigger than 0";
pub const parse_lto: &str =
@ -592,6 +593,41 @@ fn parse_mir_spanview(slot: &mut Option<MirSpanview>, v: Option<&str>) -> bool {
true
}
fn parse_instrument_coverage(slot: &mut Option<InstrumentCoverage>, v: Option<&str>) -> bool {
if v.is_some() {
let mut bool_arg = None;
if parse_opt_bool(&mut bool_arg, v) {
*slot = if bool_arg.unwrap() {
Some(InstrumentCoverage::All)
} else {
None
};
return true
}
}
let v = match v {
None => {
*slot = Some(InstrumentCoverage::All);
return true;
}
Some(v) => v,
};
*slot = Some(match v {
"all" => InstrumentCoverage::All,
"except-unused-generics" | "except_unused_generics" => {
InstrumentCoverage::ExceptUnusedGenerics
}
"except-unused-functions" | "except_unused_functions" => {
InstrumentCoverage::ExceptUnusedFunctions
}
"off" | "no" | "n" | "false" | "0" => InstrumentCoverage::Off,
_ => return false,
});
true
}
fn parse_treat_err_as_bug(slot: &mut Option<NonZeroUsize>, v: Option<&str>) -> bool {
match v {
Some(s) => { *slot = s.parse().ok(); slot.is_some() }
@ -967,12 +1003,14 @@ fn parse_split_debuginfo(slot: &mut Option<SplitDebuginfo>, v: Option<&str>) ->
"control whether `#[inline]` functions are in all CGUs"),
input_stats: bool = (false, parse_bool, [UNTRACKED],
"gather statistics about the input (default: no)"),
instrument_coverage: bool = (false, parse_bool, [TRACKED],
instrument_coverage: Option<InstrumentCoverage> = (None, parse_instrument_coverage, [TRACKED],
"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 `-Z symbol-mangling-version=v0`; disables/overrides some Rust \
optimizations (default: no)"),
optimizations. Optional values are: `=all` (default coverage), \
`=except-unused-generics`, `=except-unused-functions`, or `=off` \
(default: instrument-coverage=off)"),
instrument_mcount: bool = (false, parse_bool, [TRACKED],
"insert function instrument code for mcount-based tracing (default: no)"),
keep_hygiene_data: bool = (false, parse_bool, [UNTRACKED],

View file

@ -1150,6 +1150,21 @@ pub fn link_dead_code(&self) -> bool {
self.opts.cg.link_dead_code.unwrap_or(false)
}
pub fn instrument_coverage(&self) -> bool {
self.opts.debugging_opts.instrument_coverage.unwrap_or(config::InstrumentCoverage::Off)
!= config::InstrumentCoverage::Off
}
pub fn instrument_coverage_except_unused_generics(&self) -> bool {
self.opts.debugging_opts.instrument_coverage.unwrap_or(config::InstrumentCoverage::Off)
== config::InstrumentCoverage::ExceptUnusedGenerics
}
pub fn instrument_coverage_except_unused_functions(&self) -> bool {
self.opts.debugging_opts.instrument_coverage.unwrap_or(config::InstrumentCoverage::Off)
== config::InstrumentCoverage::ExceptUnusedFunctions
}
pub fn mark_attr_known(&self, attr: &Attribute) {
self.known_attrs.lock().mark(attr)
}

View file

@ -2875,7 +2875,19 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
.emit();
InlineAttr::None
} else if list_contains_name(&items[..], sym::always) {
InlineAttr::Always
if tcx.sess.instrument_coverage() {
// Forced inlining will discard functions marked with `#[inline(always)]`.
// If `-Z instrument-coverage` is enabled, the generated coverage map may
// hold references to functions that no longer exist, causing errors in
// coverage reports. (Note, this fixes #82875. I added some tests that
// also include `#[inline(always)]` functions, used and unused, and within
// and across crates, but could not reproduce the reported error in the
// `rustc` test suite. I am able to reproduce the error, following the steps
// described in #82875, and this change does fix that issue.)
InlineAttr::Hint
} else {
InlineAttr::Always
}
} else if list_contains_name(&items[..], sym::never) {
InlineAttr::Never
} else {

View file

@ -17,7 +17,7 @@ else
COMDAT_IF_SUPPORTED=, comdat
endif
DEFINE_INTERNAL=define internal
DEFINE_INTERNAL=define hidden
ifdef IS_WINDOWS
LLVM_FILECHECK_OPTIONS=\

View file

@ -59,7 +59,7 @@ endif
# if and when we allow `llvm-cov` to produce results for multiple files. Note, the path separators
# appear to be normalized to `/` in those files, thankfully.)
LLVM_COV_IGNORE_FILES=\
--ignore-filename-regex=uses_crate.rs
--ignore-filename-regex='(uses_crate.rs|uses_inline_crate.rs)'
# When generating `expected_*` results (using `x.py test --bless`), the `--debug` flag is forced.
# If assertions are disabled, the command will fail with an error, rather than attempt to generate
@ -82,13 +82,13 @@ endif
%: $(SOURCEDIR)/lib/%.rs
# Compile the test library with coverage instrumentation
$(RUSTC) $(SOURCEDIR)/lib/$@.rs \
$$( sed -nE 's#^// compile-flags:(.*)#\1# p' $(SOURCEDIR)/lib/$@.rs) \
$$( sed -n 's/^\/\/ compile-flags: \([^#]*\).*/\1/p' $(SOURCEDIR)/lib/$@.rs ) \
--crate-type rlib -Zinstrument-coverage
%: $(SOURCEDIR)/%.rs
# Compile the test program with coverage instrumentation
$(RUSTC) $(SOURCEDIR)/$@.rs \
$$( sed -nE 's#^// compile-flags:(.*)#\1# p' $(SOURCEDIR)/$@.rs) \
$$( sed -n 's/^\/\/ compile-flags: \([^#]*\).*/\1/p' $(SOURCEDIR)/$@.rs ) \
-L "$(TMPDIR)" -Zinstrument-coverage
# Run it in order to generate some profiling data,
@ -107,7 +107,7 @@ endif
# Run it through rustdoc as well to cover doctests
LLVM_PROFILE_FILE="$(TMPDIR)"/$@-%p.profraw \
$(RUSTDOC) --crate-name workaround_for_79771 --test $(SOURCEDIR)/$@.rs \
$$( sed -nE 's#^// compile-flags:(.*)#\1# p' $(SOURCEDIR)/$@.rs) \
$$( sed -n 's/^\/\/ compile-flags: \([^#]*\).*/\1/p' $(SOURCEDIR)/$@.rs ) \
-L "$(TMPDIR)" -Zinstrument-coverage \
-Z unstable-options --persist-doctests=$(TMPDIR)/rustdoc-$@

View file

@ -1,6 +1,6 @@
1| |#![allow(unused_assignments, dead_code)]
2| |
3| |// compile-flags: --edition=2018
3| |// compile-flags: --edition=2018 -C opt-level=1 # fix in rustc_mir/monomorphize/partitioning/mod.rs
4| |
5| 1|async fn c(x: u8) -> u8 {
6| 1| if x == 8 {
@ -10,7 +10,7 @@
10| | }
11| 1|}
12| |
13| 0|async fn d() -> u8 { 1 }
13| |async fn d() -> u8 { 1 } // should have a coverage count `0` (see below)
14| |
15| 0|async fn e() -> u8 { 1 } // unused function; executor does not block on `g()`
16| |
@ -132,4 +132,15 @@
126| | }
127| 1| }
128| |}
129| |
130| |// `llvm-cov show` shows no coverage results for the `d()`, even though the
131| |// crate's LLVM IR shows the function exists and has an InstrProf PGO counter,
132| |// and appears to be registered like all other counted functions.
133| |//
134| |// `llvm-cov show --debug` output shows there is at least one `Counter` for this
135| |// line, but counters do not appear in the `Combined regions` section (unlike
136| |// `f()`, which is similar, but does appear in `Combined regions`, and does show
137| |// coverage). The only difference is, `f()` is awaited, but the call to await
138| |// `d()` is not reached. (Note: `d()` will appear in coverage if the test is
139| |// modified to cause it to be awaited.)

View file

@ -1,5 +1,5 @@
1| |#![allow(unused_assignments, unused_variables)]
2| |
2| |// compile-flags: -C opt-level=2 # fix described in rustc_middle/mir/mono.rs
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

View file

@ -23,6 +23,12 @@
22| 1|//! ```
23| 2|//! #[derive(Debug, PartialEq)]
^1
------------------
| Unexecuted instantiation: <rust_out::main::_doctest_main____coverage_doctest_rs_22_0::SomeError as core::cmp::PartialEq>::ne
------------------
| <rust_out::main::_doctest_main____coverage_doctest_rs_22_0::SomeError as core::cmp::PartialEq>::eq:
| 23| 2|//! #[derive(Debug, PartialEq)]
------------------
24| 1|//! struct SomeError {
25| 1|//! msg: String,
26| 1|//! }

View file

@ -29,12 +29,12 @@
18| 2| println!("BOOM times {}!!!", self.strength);
19| 2| }
------------------
| <generics::Firework<i32> as core::ops::drop::Drop>::drop:
| <generics::Firework<f64> 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:
| <generics::Firework<i32> as core::ops::drop::Drop>::drop:
| 17| 1| fn drop(&mut self) {
| 18| 1| println!("BOOM times {}!!!", self.strength);
| 19| 1| }

View file

@ -3,6 +3,11 @@
3| |
4| 2|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
^0 ^0 ^0 ^0 ^1 ^1 ^0^0
------------------
| Unexecuted instantiation: <partial_eq::Version as core::cmp::PartialEq>::ne
------------------
| Unexecuted instantiation: <partial_eq::Version as core::cmp::PartialEq>::eq
------------------
5| |pub struct Version {
6| | major: usize,
7| | minor: usize,

View file

@ -0,0 +1,62 @@
1| 2|fn foo<T>(x: T) {
2| 2| let mut i = 0;
3| 22| while i < 10 {
4| 20| i != 0 || i != 0;
^2
5| 20| i += 1;
6| | }
7| 2|}
------------------
| unused::foo::<f32>:
| 1| 1|fn foo<T>(x: T) {
| 2| 1| let mut i = 0;
| 3| 11| while i < 10 {
| 4| 10| i != 0 || i != 0;
| ^1
| 5| 10| i += 1;
| 6| | }
| 7| 1|}
------------------
| unused::foo::<u32>:
| 1| 1|fn foo<T>(x: T) {
| 2| 1| let mut i = 0;
| 3| 11| while i < 10 {
| 4| 10| i != 0 || i != 0;
| ^1
| 5| 10| i += 1;
| 6| | }
| 7| 1|}
------------------
8| |
9| 0|fn unused_template_func<T>(x: T) {
10| 0| let mut i = 0;
11| 0| while i < 10 {
12| 0| i != 0 || i != 0;
13| 0| i += 1;
14| | }
15| 0|}
16| |
17| 0|fn unused_func(mut a: u32) {
18| 0| if a != 0 {
19| 0| a += 1;
20| 0| }
21| 0|}
22| |
23| 0|fn unused_func2(mut a: u32) {
24| 0| if a != 0 {
25| 0| a += 1;
26| 0| }
27| 0|}
28| |
29| 0|fn unused_func3(mut a: u32) {
30| 0| if a != 0 {
31| 0| a += 1;
32| 0| }
33| 0|}
34| |
35| 1|fn main() -> Result<(), u8> {
36| 1| foo::<u32>(0);
37| 1| foo::<f32>(0.0);
38| 1| Ok(())
39| 1|}

View file

@ -1,5 +1,5 @@
1| |#![allow(unused_assignments, unused_variables)]
2| |
2| |// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
3| |use std::fmt::Debug;
4| |
5| 1|pub fn used_function() {
@ -29,7 +29,9 @@
| 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
| 19| 1|}
------------------
20| |
| Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_>
------------------
20| |// Expect for above function: `Unexecuted instantiation` (see below)
21| 2|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
22| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
23| 2|}
@ -63,6 +65,17 @@
29| 2|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
30| 2| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
31| 2|}
------------------
| used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>:
| 29| 1|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
| 30| 1| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
| 31| 1|}
------------------
| used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>:
| 29| 1|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
| 30| 1| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
| 31| 1|}
------------------
32| |
33| 0|pub fn unused_generic_function<T: Debug>(arg: T) {
34| 0| println!("unused_generic_function with {:?}", arg);
@ -94,46 +107,42 @@
60| 1| used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
61| 1|}
62| |
63| |// FIXME(#79651): `used_from_bin_crate_and_lib_crate_generic_function()` is covered and executed
64| |// `2` times, but the coverage output also shows (at the bottom of the coverage report):
65| |// ------------------
66| |// | Unexecuted instantiation: <some function name here>
67| |// ------------------
68| |//
69| |// Note, the function name shown in the error seems to change depending on the structure of the
70| |// code, for some reason, including:
71| |//
72| |// * used_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>
73| |// * used_crate::use_this_lib_crate
63| |// FIXME(#79651): "Unexecuted instantiation" errors appear in coverage results,
64| |// for example:
65| |//
66| |// | Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_>
67| |//
68| |// These notices appear when `llvm-cov` shows instantiations. This may be a
69| |// default option, but it can be suppressed with:
70| |//
71| |// ```shell
72| |// $ `llvm-cov show --show-instantiations=0 ...`
73| |// ```
74| |//
75| |// The `Unexecuted instantiation` error may be related to more than one generic function. Since the
76| |// reporting is not consistent, it may not be obvious if there are multiple problems here; however,
77| |// `used_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>` (which I have seen
78| |// with this error) is the only generic function missing instantiaion coverage counts.
75| |// The notice is triggered because the function is unused by the library itself,
76| |// and when the library is compiled, a synthetic function is generated, so
77| |// unused function coverage can be reported. Coverage can be skipped for unused
78| |// generic functions with:
79| |//
80| |// The `&str` variant was called from within this `lib` crate, and the `bin` crate also calls this
81| |// function, but with `T` type `&Vec<i32>`.
82| |//
83| |// I believe the reason is that one or both crates are generating `Zero` counters for what it
84| |// believes are "Unreachable" instantiations, but those instantiations are counted from the
85| |// coverage map in the other crate.
86| |//
87| |// See `add_unreachable_coverage()` in `mapgen.rs` for more on how these `Zero` counters are added
88| |// for what the funciton believes are `DefId`s that did not get codegenned. I suspect the issue
89| |// may be related to this process, but this needs to be confirmed. It may not be possible to know
90| |// for sure if a function is truly unused and should be reported with `Zero` coverage if it may
91| |// still get used from an external crate. (Something to look at: If the `DefId` in MIR corresponds
92| |// _only_ to the generic function without type parameters, is the `DefId` in the codegenned set,
93| |// instantiated with one of the type parameters (in either or both crates) a *different* `DefId`?
94| |// If so, `add_unreachable_coverage()` would assume the MIR `DefId` was uncovered, and would add
95| |// unreachable coverage.
96| |//
97| |// I didn't think they could be different, but if they can, we would need to find the `DefId` for
98| |// the generic function MIR and include it in the set of "codegenned" DefIds if any instantiation
99| |// of that generic function does exist.
100| |//
101| |// Note, however, for `used_with_same_type_from_bin_crate_and_lib_crate_generic_function()` both
102| |// crates use this function with the same type variant. The function does not have multiple
103| |// instantiations, so the coverage analysis is not confused. No "Unexecuted instantiations" errors
104| |// are reported.
80| |// ```shell
81| |// $ `rustc -Z instrument-coverage=except-unused-generics ...`
82| |// ```
83| |//
84| |// Even though this function is used by `uses_crate.rs` (and
85| |// counted), with substitutions for `T`, those instantiations are only generated
86| |// when the generic function is actually used (from the binary, not from this
87| |// library crate). So the test result shows coverage for all instantiated
88| |// versions and their generic type substitutions, plus the `Unexecuted
89| |// instantiation` message for the non-substituted version. This is valid, but
90| |// unfortunately a little confusing.
91| |//
92| |// The library crate has its own coverage map, and the only way to show unused
93| |// coverage of a generic function is to include the generic function in the
94| |// coverage map, marked as an "unused function". If the library were used by
95| |// another binary that never used this generic function, then it would be valid
96| |// to show the unused generic, with unknown substitution (`_`).
97| |//
98| |// The alternative is to exclude all generics from being included in the "unused
99| |// functions" list, which would then omit coverage results for
100| |// `unused_generic_function<T>()`, below.

View file

@ -0,0 +1,156 @@
1| |#![allow(unused_assignments, unused_variables)]
2| |
3| |// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
4| |
5| |use std::fmt::Debug;
6| |
7| 1|pub fn used_function() {
8| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
9| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
10| | // dependent conditions.
11| 1| let is_true = std::env::args().len() == 1;
12| 1| let mut countdown = 0;
13| 1| if is_true {
14| 1| countdown = 10;
15| 1| }
^0
16| 1| use_this_lib_crate();
17| 1|}
18| |
19| |#[inline(always)]
20| 1|pub fn used_inline_function() {
21| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
22| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
23| | // dependent conditions.
24| 1| let is_true = std::env::args().len() == 1;
25| 1| let mut countdown = 0;
26| 1| if is_true {
27| 1| countdown = 10;
28| 1| }
^0
29| 1| use_this_lib_crate();
30| 1|}
------------------
| used_inline_crate::used_inline_function:
| 20| 1|pub fn used_inline_function() {
| 21| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
| 22| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
| 23| | // dependent conditions.
| 24| 1| let is_true = std::env::args().len() == 1;
| 25| 1| let mut countdown = 0;
| 26| 1| if is_true {
| 27| 1| countdown = 10;
| 28| 1| }
| ^0
| 29| 1| use_this_lib_crate();
| 30| 1|}
------------------
| Unexecuted instantiation: used_inline_crate::used_inline_function
------------------
31| |// Expect for above function:
32| |//
33| |// | Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_>
34| |//
35| |// With `#[inline(always)]` this function is instantiated twice, in both the library crate (which
36| |// does not use it) and the `uses_inline_crate` binary (which does use/call it).
37| |
38| |#[inline(always)]
39| 2|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
40| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
41| 2|}
------------------
| used_inline_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
| 39| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
| 40| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
| 41| 1|}
------------------
| used_inline_crate::used_only_from_bin_crate_generic_function::<&str>:
| 39| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
| 40| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
| 41| 1|}
------------------
| Unexecuted instantiation: used_inline_crate::used_only_from_bin_crate_generic_function::<_>
------------------
42| |// Expect for above function: `Unexecuted instantiation` (see notes in `used_crate.rs`)
43| |
44| |#[inline(always)]
45| 4|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
46| 4| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
47| 4|}
------------------
| used_inline_crate::used_only_from_this_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
| 45| 2|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
| 46| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
| 47| 2|}
------------------
| used_inline_crate::used_only_from_this_lib_crate_generic_function::<&str>:
| 45| 2|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
| 46| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
| 47| 2|}
------------------
48| |
49| |#[inline(always)]
50| 3|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
51| 3| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
52| 3|}
------------------
| used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
| 50| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
| 51| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
| 52| 1|}
------------------
| used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>:
| 50| 2|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
| 51| 2| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
| 52| 2|}
------------------
53| |
54| |#[inline(always)]
55| 3|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
56| 3| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
57| 3|}
------------------
| used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>:
| 55| 1|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
| 56| 1| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
| 57| 1|}
------------------
| used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>:
| 55| 2|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
| 56| 2| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
| 57| 2|}
------------------
58| |
59| |#[inline(always)]
60| 0|pub fn unused_generic_function<T: Debug>(arg: T) {
61| 0| println!("unused_generic_function with {:?}", arg);
62| 0|}
63| |
64| |#[inline(always)]
65| 0|pub fn unused_function() {
66| 0| let is_true = std::env::args().len() == 1;
67| 0| let mut countdown = 2;
68| 0| if !is_true {
69| 0| countdown = 20;
70| 0| }
71| 0|}
72| |
73| |#[inline(always)]
74| 0|fn unused_private_function() {
75| 0| let is_true = std::env::args().len() == 1;
76| 0| let mut countdown = 2;
77| 0| if !is_true {
78| 0| countdown = 20;
79| 0| }
80| 0|}
81| |
82| 2|fn use_this_lib_crate() {
83| 2| used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
84| 2| used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
85| 2| "used from library used_crate.rs",
86| 2| );
87| 2| let some_vec = vec![5, 6, 7, 8];
88| 2| used_only_from_this_lib_crate_generic_function(some_vec);
89| 2| used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
90| 2|}

View file

@ -38,13 +38,11 @@ endif
%: $(SOURCEDIR)/lib/%.rs
# Compile the test library with coverage instrumentation
$(RUSTC) $(SOURCEDIR)/lib/$@.rs \
$$( sed -nE 's#^// compile-flags:(.*)#\1# p' $(SOURCEDIR)/lib/$@.rs) \
$$( sed -n 's/^\/\/ compile-flags: \([^#]*\).*/\1/p' $(SOURCEDIR)/lib/$@.rs ) \
--crate-type rlib \
-Ztrim-diagnostic-paths=no \
-Zinstrument-coverage \
-Zdump-mir=InstrumentCoverage \
-Zdump-mir-spanview \
-Zdump-mir-dir="$(TMPDIR)"/mir_dump.$@
-Zdump-mir=InstrumentCoverage -Zdump-mir-spanview -Zdump-mir-dir="$(TMPDIR)"/mir_dump.$@ \
-Zinstrument-coverage
for path in "$(TMPDIR)"/mir_dump.$@/*; do \
file="$$(basename "$$path")"; \
@ -68,13 +66,11 @@ endif
%: $(SOURCEDIR)/%.rs
# Compile the test program with coverage instrumentation
$(RUSTC) $(SOURCEDIR)/$@.rs \
$$( sed -nE 's#^// compile-flags:(.*)#\1# p' $(SOURCEDIR)/$@.rs) \
$$( sed -n 's/^\/\/ compile-flags: \([^#]*\).*/\1/p' $(SOURCEDIR)/$@.rs ) \
-L "$(TMPDIR)" \
-Ztrim-diagnostic-paths=no \
-Zinstrument-coverage \
-Zdump-mir=InstrumentCoverage \
-Zdump-mir-spanview \
-Zdump-mir-dir="$(TMPDIR)"/mir_dump.$@
-Zdump-mir=InstrumentCoverage -Zdump-mir-spanview -Zdump-mir-dir="$(TMPDIR)"/mir_dump.$@ \
-Zinstrument-coverage
for path in "$(TMPDIR)"/mir_dump.$@/*; do \
file="$$(basename "$$path")"; \

View file

@ -74,18 +74,16 @@ For revisions in Pull Requests (PR):
<span class="line"><span class="code even" style="--layer: 1" title="42:11-42:12: @0[3]: FakeRead(ForMatchedPlace, _3)"> // (b) the open brace for the function body, counted once when the body is</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="42:11-42:12: @0[3]: FakeRead(ForMatchedPlace, _3)"> // executed asynchronously.</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="42:11-42:12: @0[3]: FakeRead(ForMatchedPlace, _3)"> match x<span class="annotation">⦉@0,3,4</span></span></span><span class="code" style="--layer: 0"> {</span></span>
<span class="line"><span class="code" style="--layer: 0"> </span><span><span class="code odd" style="--layer: 1" title="43:9-43:10: @18[3]: _4 = _3"><span class="annotation">@18,20</span>y<span class="annotation">⦉@18,20</span></span></span><span class="code" style="--layer: 0"> if </span><span><span class="code even" style="--layer: 1" title="43:16-43:17: @3[6]: _9 = _3
43:14-43:18: @3.Call: _8 = c(move _9) -&gt; [return: bb4, unwind: bb88]
<span class="line"><span class="code" style="--layer: 0"> </span><span><span class="code odd" style="--layer: 1" title="43:9-43:10: @17[3]: _4 = _3"><span class="annotation">@17,19</span>y<span class="annotation">⦉@17,19</span></span></span><span class="code" style="--layer: 0"> if </span><span><span class="code even" style="--layer: 1" title="43:16-43:17: @3[6]: _9 = _3
43:14-43:18: @3.Call: _8 = c(move _9) -&gt; [return: bb4, unwind: bb82]
43:14-43:18: @4[1]: FakeRead(ForMatchedPlace, _8)"><span class="annotation">@0,3,4⦊</span>c(x)<span class="annotation">⦉@0,3,4</span></span></span><span class="code" style="--layer: 0">.await == </span><span><span class="code odd" style="--layer: 1" title="43:28-43:29: @15[3]: _26 = (*_5)
43:28-43:33: @15[4]: _27 = CheckedAdd(_26, const 1_u8)
43:28-43:33: @16[0]: _25 = move (_27.0: u8)"><span class="annotation">@10,13,15,16,17⦊</span>y + 1<span class="annotation">⦉@10,13,15,16,17</span></span></span><span class="code" style="--layer: 0"> =&gt; { </span><span><span class="code even" style="--layer: 1" title="43:39-43:42: @18.Call: _29 = d() -&gt; [return: bb20, unwind: bb79]
43:39-43:42: @20[0]: FakeRead(ForMatchedPlace, _29)"><span class="annotation">@18,20⦊</span>d()<span class="annotation">⦉@18,20</span></span></span><span class="code" style="--layer: 0">.await; }</span></span>
<span class="line"><span class="code" style="--layer: 0"> </span><span><span class="code odd" style="--layer: 1" title="44:9-44:10: @48[3]: _44 = _3"><span class="annotation">@48⦊</span>y<span class="annotation">⦉@48</span></span></span><span class="code" style="--layer: 0"> if </span><span><span class="code even" style="--layer: 1" title="44:14-44:17: @33.Call: _48 = f() -&gt; [return: bb34, unwind: bb72]
44:14-44:17: @34[0]: FakeRead(ForMatchedPlace, _48)"><span class="annotation">@1,33,34⦊</span>f()<span class="annotation">⦉@1,33,34</span></span></span><span class="code" style="--layer: 0">.await == </span><span><span class="code odd" style="--layer: 1" title="44:27-44:28: @45[3]: _64 = (*_45)
44:27-44:32: @45[4]: _65 = CheckedAdd(_64, const 1_u8)
44:27-44:32: @46[0]: _63 = move (_65.0: u8)"><span class="annotation">@40,43,45,46,47⦊</span>y + 1<span class="annotation">⦉@40,43,45,46,47</span></span></span><span class="code" style="--layer: 0"> =&gt; </span><span><span class="code even" style="--layer: 1" title="44:36-44:38: @48[4]: _0 = ()"><span class="annotation">@48⦊</span>()<span class="annotation">⦉@48</span></span></span><span class="code" style="--layer: 0">,</span></span>
43:28-43:33: @15[4]: _25 = Add(move _26, const 1_u8)"><span class="annotation">@10,13,15,16⦊</span>y + 1<span class="annotation">⦉@10,13,15,16</span></span></span><span class="code" style="--layer: 0"> =&gt; { </span><span><span class="code even" style="--layer: 1" title="43:39-43:42: @17.Call: _28 = d() -&gt; [return: bb19, unwind: bb75]
43:39-43:42: @19[0]: FakeRead(ForMatchedPlace, _28)"><span class="annotation">@17,19⦊</span>d()<span class="annotation">⦉@17,19</span></span></span><span class="code" style="--layer: 0">.await; }</span></span>
<span class="line"><span class="code" style="--layer: 0"> </span><span><span class="code odd" style="--layer: 1" title="44:9-44:10: @46[3]: _43 = _3"><span class="annotation">@46⦊</span>y<span class="annotation">⦉@46</span></span></span><span class="code" style="--layer: 0"> if </span><span><span class="code even" style="--layer: 1" title="44:14-44:17: @32.Call: _47 = f() -&gt; [return: bb33, unwind: bb68]
44:14-44:17: @33[0]: FakeRead(ForMatchedPlace, _47)"><span class="annotation">@1,32,33⦊</span>f()<span class="annotation">⦉@1,32,33</span></span></span><span class="code" style="--layer: 0">.await == </span><span><span class="code odd" style="--layer: 1" title="44:27-44:28: @44[3]: _63 = (*_44)
44:27-44:32: @44[4]: _62 = Add(move _63, const 1_u8)"><span class="annotation">@39,42,44,45⦊</span>y + 1<span class="annotation">⦉@39,42,44,45</span></span></span><span class="code" style="--layer: 0"> =&gt; </span><span><span class="code even" style="--layer: 1" title="44:36-44:38: @46[4]: _0 = ()"><span class="annotation">@46⦊</span>()<span class="annotation">⦉@46</span></span></span><span class="code" style="--layer: 0">,</span></span>
<span class="line"><span class="code" style="--layer: 0"> _ =&gt; </span><span><span class="code odd" style="--layer: 1" title="45:14-45:16: @2[0]: _0 = ()"><span class="annotation">@2⦊</span>()<span class="annotation">⦉@2</span></span></span><span class="code" style="--layer: 0">,</span></span>
<span class="line"><span class="code" style="--layer: 0"> }</span></span>
<span class="line"><span class="code" style="--layer: 0">}</span><span><span class="code even" style="--layer: 1" title="47:2-47:2: @51.Return: return"><span class="annotation">@50,51</span><span class="annotation">⦉@50,51</span></span></span></span></div>
<span class="line"><span class="code" style="--layer: 0">}</span><span><span class="code even" style="--layer: 1" title="47:2-47:2: @49.Return: return"><span class="annotation">@48,49</span><span class="annotation">⦉@48,49</span></span></span></span></div>
</body>
</html>

View file

@ -69,7 +69,7 @@ For revisions in Pull Requests (PR):
</style>
</head>
<body>
<div class="code" style="counter-reset: line 48"><span class="line"><span><span class="code even" style="--layer: 1" title="68:11-68:12: @0[0]: FakeRead(ForMatchedPlace, _1)"><span class="annotation">@0,3,4,5</span>fn j(x: u8) {</span></span>
<div class="code" style="counter-reset: line 48"><span class="line"><span><span class="code even" style="--layer: 1" title="68:11-68:12: @0[0]: FakeRead(ForMatchedPlace, _1)"><span class="annotation">@0,3,4⦊</span>fn j(x: u8) {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="68:11-68:12: @0[0]: FakeRead(ForMatchedPlace, _1)"> // non-async versions of `c()`, `d()`, and `f()` to make it similar to async `i()`.</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="68:11-68:12: @0[0]: FakeRead(ForMatchedPlace, _1)"> fn c(x: u8) -&gt; u8 {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="68:11-68:12: @0[0]: FakeRead(ForMatchedPlace, _1)"> if x == 8 {</span></span>
@ -88,21 +88,19 @@ For revisions in Pull Requests (PR):
<span class="line"><span class="code even" style="--layer: 1" title="68:11-68:12: @0[0]: FakeRead(ForMatchedPlace, _1)"> }</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="68:11-68:12: @0[0]: FakeRead(ForMatchedPlace, _1)"> fn d() -&gt; u8 { 1 }</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="68:11-68:12: @0[0]: FakeRead(ForMatchedPlace, _1)"> fn f() -&gt; u8 { 1 }</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="68:11-68:12: @0[0]: FakeRead(ForMatchedPlace, _1)"> match x<span class="annotation">⦉@0,3,4,5</span></span></span><span class="code" style="--layer: 0"> {</span></span>
<span class="line"><span class="code" style="--layer: 0"> </span><span><span class="code odd" style="--layer: 1" title="69:9-69:10: @6[3]: _2 = _1"><span class="annotation">@6,8</span>y<span class="annotation">⦉@6,8</span></span></span><span class="code" style="--layer: 0"> if </span><span><span class="code even" style="--layer: 1" title="69:16-69:17: @3[5]: _6 = _1
69:14-69:18: @3.Call: _5 = j::c(move _6) -&gt; [return: bb4, unwind: bb15]
<span class="line"><span class="code even" style="--layer: 1" title="68:11-68:12: @0[0]: FakeRead(ForMatchedPlace, _1)"> match x<span class="annotation">⦉@0,3,4</span></span></span><span class="code" style="--layer: 0"> {</span></span>
<span class="line"><span class="code" style="--layer: 0"> </span><span><span class="code odd" style="--layer: 1" title="69:9-69:10: @5[3]: _2 = _1"><span class="annotation">@5,7</span>y<span class="annotation">⦉@5,7</span></span></span><span class="code" style="--layer: 0"> if </span><span><span class="code even" style="--layer: 1" title="69:16-69:17: @3[5]: _6 = _1
69:14-69:18: @3.Call: _5 = j::c(move _6) -&gt; [return: bb4, unwind: bb13]
69:22-69:23: @4[3]: _8 = (*_3)
69:22-69:27: @4[4]: _9 = CheckedAdd(_8, const 1_u8)
69:22-69:27: @5[0]: _7 = move (_9.0: u8)
69:14-69:27: @5[2]: _4 = Eq(move _5, move _7)"><span class="annotation">@0,3,4,5⦊</span>c(x) == y + 1<span class="annotation">⦉@0,3,4,5</span></span></span><span class="code" style="--layer: 0"> =&gt; </span><span><span class="code odd" style="--layer: 1" title="69:33-69:36: @6.Call: _10 = j::d() -&gt; [return: bb8, unwind: bb15]
69:31-69:39: @8[1]: _0 = const ()"><span class="annotation">@6,8⦊</span>{ d(); }<span class="annotation">⦉@6,8</span></span></span><span class="code" style="--layer: 0"></span></span>
<span class="line"><span class="code" style="--layer: 0"> </span><span><span class="code even" style="--layer: 1" title="70:9-70:10: @12[3]: _11 = _1"><span class="annotation">@12⦊</span>y<span class="annotation">⦉@12</span></span></span><span class="code" style="--layer: 0"> if </span><span><span class="code odd" style="--layer: 1" title="70:14-70:17: @9.Call: _14 = j::f() -&gt; [return: bb10, unwind: bb15]
70:21-70:22: @10[2]: _16 = (*_12)
70:21-70:26: @10[3]: _17 = CheckedAdd(_16, const 1_u8)
70:21-70:26: @11[0]: _15 = move (_17.0: u8)
70:14-70:26: @11[2]: _13 = Eq(move _14, move _15)"><span class="annotation">@1,9,10,11⦊</span>f() == y + 1<span class="annotation">⦉@1,9,10,11</span></span></span><span class="code" style="--layer: 0"> =&gt; </span><span><span class="code even" style="--layer: 1" title="70:30-70:32: @12[4]: _0 = ()"><span class="annotation">@12⦊</span>()<span class="annotation">⦉@12</span></span></span><span class="code" style="--layer: 0">,</span></span>
69:22-69:27: @4[4]: _7 = Add(move _8, const 1_u8)
69:14-69:27: @4[6]: _4 = Eq(move _5, move _7)"><span class="annotation">@0,3,4⦊</span>c(x) == y + 1<span class="annotation">⦉@0,3,4</span></span></span><span class="code" style="--layer: 0"> =&gt; </span><span><span class="code odd" style="--layer: 1" title="69:33-69:36: @5.Call: _9 = j::d() -&gt; [return: bb7, unwind: bb13]
69:31-69:39: @7[1]: _0 = const ()"><span class="annotation">@5,7⦊</span>{ d(); }<span class="annotation">⦉@5,7</span></span></span><span class="code" style="--layer: 0"></span></span>
<span class="line"><span class="code" style="--layer: 0"> </span><span><span class="code even" style="--layer: 1" title="70:9-70:10: @10[3]: _10 = _1"><span class="annotation">@10⦊</span>y<span class="annotation">⦉@10</span></span></span><span class="code" style="--layer: 0"> if </span><span><span class="code odd" style="--layer: 1" title="70:14-70:17: @8.Call: _13 = j::f() -&gt; [return: bb9, unwind: bb13]
70:21-70:22: @9[2]: _15 = (*_11)
70:21-70:26: @9[3]: _14 = Add(move _15, const 1_u8)
70:14-70:26: @9[5]: _12 = Eq(move _13, move _14)"><span class="annotation">@1,8,9⦊</span>f() == y + 1<span class="annotation">⦉@1,8,9</span></span></span><span class="code" style="--layer: 0"> =&gt; </span><span><span class="code even" style="--layer: 1" title="70:30-70:32: @10[4]: _0 = ()"><span class="annotation">@10⦊</span>()<span class="annotation">⦉@10</span></span></span><span class="code" style="--layer: 0">,</span></span>
<span class="line"><span class="code" style="--layer: 0"> _ =&gt; </span><span><span class="code odd" style="--layer: 1" title="71:14-71:16: @2[0]: _0 = ()"><span class="annotation">@2⦊</span>()<span class="annotation">⦉@2</span></span></span><span class="code" style="--layer: 0">,</span></span>
<span class="line"><span class="code" style="--layer: 0"> }</span></span>
<span class="line"><span class="code" style="--layer: 0">}</span><span><span class="code even" style="--layer: 1" title="73:2-73:2: @14.Return: return"><span class="annotation">@14</span><span class="annotation">⦉@14</span></span></span></span></div>
<span class="line"><span class="code" style="--layer: 0">}</span><span><span class="code even" style="--layer: 1" title="73:2-73:2: @12.Return: return"><span class="annotation">@12</span><span class="annotation">⦉@12</span></span></span></span></div>
</body>
</html>

View file

@ -72,8 +72,7 @@ For revisions in Pull Requests (PR):
<div class="code" style="counter-reset: line 90"><span class="line"> <span><span class="code even" style="--layer: 1" title="91:25-91:34: @0[1]: _3 = (_1.0: u8)
91:25-91:34: @0[2]: FakeRead(ForLet, _3)
91:27-91:28: @0[4]: _4 = _3
91:27-91:32: @0[5]: _5 = CheckedSub(_4, const 1_u8)
91:27-91:32: @1[0]: _0 = move (_5.0: u8)
91:34-91:34: @1.Return: return"><span class="annotation">@0,1⦊</span>{ x - 1 }<span class="annotation">⦉@0,1</span></span></span></span></div>
91:27-91:32: @0[5]: _0 = Sub(move _4, const 1_u8)
91:34-91:34: @0.Return: return"><span class="annotation">@0⦊</span>{ x - 1 }<span class="annotation">⦉@0</span></span></span></span></div>
</body>
</html>

View file

@ -69,9 +69,8 @@ For revisions in Pull Requests (PR):
</style>
</head>
<body>
<div class="code" style="counter-reset: line 130"><span class="line"> <span class="code" style="--layer: 0">| _unused_arg: u8 | </span><span><span class="code even" style="--layer: 1" title="131:53-131:67: @0[0]: _3 = CheckedAdd((*((*_1).0: &amp;mut i32)), const 1_i32)
131:53-131:67: @1[0]: (*((*_1).0: &amp;mut i32)) = move (_3.0: i32)
131:53-131:67: @1[1]: _0 = const ()
131:67-131:67: @1.Return: return"><span class="annotation">@0,1⦊</span>countdown += 1<span class="annotation">⦉@0,1</span></span></span></span></div>
<div class="code" style="counter-reset: line 130"><span class="line"> <span class="code" style="--layer: 0">| _unused_arg: u8 | </span><span><span class="code even" style="--layer: 1" title="131:53-131:67: @0[0]: (*((*_1).0: &amp;mut i32)) = Add((*((*_1).0: &amp;mut i32)), const 1_i32)
131:53-131:67: @0[1]: _0 = const ()
131:67-131:67: @0.Return: return"><span class="annotation">@0⦊</span>countdown += 1<span class="annotation">⦉@0</span></span></span></span></div>
</body>
</html>

View file

@ -0,0 +1,87 @@
<!DOCTYPE html>
<!--
Preview this file as rendered HTML from the github source at:
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.foo.-------.InstrumentCoverage.0.html
For revisions in Pull Requests (PR):
* Replace "rust-lang" with the github PR author
* Replace "master" with the PR branch name
-->
<html>
<head>
<title>unused.foo - Coverage Spans</title>
<style>
.line {
counter-increment: line;
}
.line:before {
content: counter(line) ": ";
font-family: Menlo, Monaco, monospace;
font-style: italic;
width: 3.8em;
display: inline-block;
text-align: right;
filter: opacity(50%);
-webkit-user-select: none;
}
.code {
color: #dddddd;
background-color: #222222;
font-family: Menlo, Monaco, monospace;
line-height: 1.4em;
border-bottom: 2px solid #222222;
white-space: pre;
display: inline-block;
}
.odd {
background-color: #55bbff;
color: #223311;
}
.even {
background-color: #ee7756;
color: #551133;
}
.code {
--index: calc(var(--layer) - 1);
padding-top: calc(var(--index) * 0.15em);
filter:
hue-rotate(calc(var(--index) * 25deg))
saturate(calc(100% - (var(--index) * 2%)))
brightness(calc(100% - (var(--index) * 1.5%)));
}
.annotation {
color: #4444ff;
font-family: monospace;
font-style: italic;
display: none;
-webkit-user-select: none;
}
body:active .annotation {
/* requires holding mouse down anywhere on the page */
display: inline-block;
}
span:hover .annotation {
/* requires hover over a span ONLY on its first line */
display: inline-block;
}
</style>
</head>
<body>
<div class="code" style="counter-reset: line 0"><span class="line"><span><span class="code even" style="--layer: 1" title="2:17-2:18: @0[1]: _2 = const 0_i32
2:9-2:14: @0[2]: FakeRead(ForLet, _2)"><span class="annotation">@0⦊</span>fn foo&lt;T&gt;(x: T) {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="2:17-2:18: @0[1]: _2 = const 0_i32
2:9-2:14: @0[2]: FakeRead(ForLet, _2)"> let mut i = 0<span class="annotation">⦉@0</span></span></span><span class="code" style="--layer: 0">;</span></span>
<span class="line"><span class="code" style="--layer: 0"> while </span><span><span class="code odd" style="--layer: 1" title="3:11-3:12: @2[2]: _5 = _2
3:11-3:17: @2[3]: _4 = Lt(move _5, const 10_i32)
3:11-3:17: @2[5]: FakeRead(ForMatchedPlace, _4)"><span class="annotation">@1,2⦊</span>i &lt; 10<span class="annotation">⦉@1,2</span></span></span><span class="code" style="--layer: 0"> {</span></span>
<span class="line"><span class="code" style="--layer: 0"> </span><span><span class="code even" style="--layer: 1" title="4:9-4:10: @5[3]: _8 = _2
4:9-4:15: @5[4]: _7 = Ne(move _8, const 0_i32)"><span class="annotation">@3,5⦊</span>i != 0<span class="annotation">⦉@3,5</span></span></span><span class="code" style="--layer: 0"> || </span><span><span class="code odd" style="--layer: 1" title="4:19-4:20: @8[2]: _10 = _2
4:19-4:25: @8[3]: _9 = Ne(move _10, const 0_i32)"><span class="annotation">@8⦊</span>i != 0<span class="annotation">⦉@8</span></span></span><span class="code" style="--layer: 0">;</span></span>
<span class="line"><span class="code" style="--layer: 0"> </span><span><span class="code even" style="--layer: 1" title="5:9-5:15: @9[3]: _11 = CheckedAdd(_2, const 1_i32)
5:9-5:15: @10[0]: _2 = move (_11.0: i32)"><span class="annotation">@9,10⦊</span>i += 1<span class="annotation">⦉@9,10</span></span></span><span class="code" style="--layer: 0">;</span></span>
<span class="line"><span class="code" style="--layer: 0"> }</span></span>
<span class="line"><span class="code" style="--layer: 0">}</span><span><span class="code odd" style="--layer: 1" title="7:2-7:2: @11.Return: return"><span class="annotation">@4,11⦊</span><span class="annotation">⦉@4,11</span></span></span></span></div>
</body>
</html>

View file

@ -0,0 +1,98 @@
<!DOCTYPE html>
<!--
Preview this file as rendered HTML from the github source at:
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.main.-------.InstrumentCoverage.0.html
For revisions in Pull Requests (PR):
* Replace "rust-lang" with the github PR author
* Replace "master" with the PR branch name
-->
<html>
<head>
<title>unused.main - Coverage Spans</title>
<style>
.line {
counter-increment: line;
}
.line:before {
content: counter(line) ": ";
font-family: Menlo, Monaco, monospace;
font-style: italic;
width: 3.8em;
display: inline-block;
text-align: right;
filter: opacity(50%);
-webkit-user-select: none;
}
.code {
color: #dddddd;
background-color: #222222;
font-family: Menlo, Monaco, monospace;
line-height: 1.4em;
border-bottom: 2px solid #222222;
white-space: pre;
display: inline-block;
}
.odd {
background-color: #55bbff;
color: #223311;
}
.even {
background-color: #ee7756;
color: #551133;
}
.code {
--index: calc(var(--layer) - 1);
padding-top: calc(var(--index) * 0.15em);
filter:
hue-rotate(calc(var(--index) * 25deg))
saturate(calc(100% - (var(--index) * 2%)))
brightness(calc(100% - (var(--index) * 1.5%)));
}
.annotation {
color: #4444ff;
font-family: monospace;
font-style: italic;
display: none;
-webkit-user-select: none;
}
body:active .annotation {
/* requires holding mouse down anywhere on the page */
display: inline-block;
}
span:hover .annotation {
/* requires hover over a span ONLY on its first line */
display: inline-block;
}
</style>
</head>
<body>
<div class="code" style="counter-reset: line 34"><span class="line"><span><span class="code even" style="--layer: 1" title="36:5-36:18: @0.Call: _1 = foo::&lt;u32&gt;(const 0_u32) -&gt; [return: bb1, unwind: bb3]
37:5-37:20: @1.Call: _2 = foo::&lt;f32&gt;(const 0f32) -&gt; [return: bb2, unwind: bb3]
38:8-38:10: @2[2]: _3 = ()
38:5-38:11: @2[3]: _0 = std::result::Result::&lt;(), u8&gt;::Ok(move _3)
39:2-39:2: @2.Return: return"><span class="annotation">@0,1,2⦊</span>fn main() -&gt; Result&lt;(), u8&gt; {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="36:5-36:18: @0.Call: _1 = foo::&lt;u32&gt;(const 0_u32) -&gt; [return: bb1, unwind: bb3]
37:5-37:20: @1.Call: _2 = foo::&lt;f32&gt;(const 0f32) -&gt; [return: bb2, unwind: bb3]
38:8-38:10: @2[2]: _3 = ()
38:5-38:11: @2[3]: _0 = std::result::Result::&lt;(), u8&gt;::Ok(move _3)
39:2-39:2: @2.Return: return"> foo::&lt;u32&gt;(0);</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="36:5-36:18: @0.Call: _1 = foo::&lt;u32&gt;(const 0_u32) -&gt; [return: bb1, unwind: bb3]
37:5-37:20: @1.Call: _2 = foo::&lt;f32&gt;(const 0f32) -&gt; [return: bb2, unwind: bb3]
38:8-38:10: @2[2]: _3 = ()
38:5-38:11: @2[3]: _0 = std::result::Result::&lt;(), u8&gt;::Ok(move _3)
39:2-39:2: @2.Return: return"> foo::&lt;f32&gt;(0.0);</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="36:5-36:18: @0.Call: _1 = foo::&lt;u32&gt;(const 0_u32) -&gt; [return: bb1, unwind: bb3]
37:5-37:20: @1.Call: _2 = foo::&lt;f32&gt;(const 0f32) -&gt; [return: bb2, unwind: bb3]
38:8-38:10: @2[2]: _3 = ()
38:5-38:11: @2[3]: _0 = std::result::Result::&lt;(), u8&gt;::Ok(move _3)
39:2-39:2: @2.Return: return"> Ok(())</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="36:5-36:18: @0.Call: _1 = foo::&lt;u32&gt;(const 0_u32) -&gt; [return: bb1, unwind: bb3]
37:5-37:20: @1.Call: _2 = foo::&lt;f32&gt;(const 0f32) -&gt; [return: bb2, unwind: bb3]
38:8-38:10: @2[2]: _3 = ()
38:5-38:11: @2[3]: _0 = std::result::Result::&lt;(), u8&gt;::Ok(move _3)
39:2-39:2: @2.Return: return">}<span class="annotation">⦉@0,1,2</span></span></span></span></div>
</body>
</html>

View file

@ -0,0 +1,86 @@
<!DOCTYPE html>
<!--
Preview this file as rendered HTML from the github source at:
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_func.-------.InstrumentCoverage.0.html
For revisions in Pull Requests (PR):
* Replace "rust-lang" with the github PR author
* Replace "master" with the PR branch name
-->
<html>
<head>
<title>unused.unused_func - Coverage Spans</title>
<style>
.line {
counter-increment: line;
}
.line:before {
content: counter(line) ": ";
font-family: Menlo, Monaco, monospace;
font-style: italic;
width: 3.8em;
display: inline-block;
text-align: right;
filter: opacity(50%);
-webkit-user-select: none;
}
.code {
color: #dddddd;
background-color: #222222;
font-family: Menlo, Monaco, monospace;
line-height: 1.4em;
border-bottom: 2px solid #222222;
white-space: pre;
display: inline-block;
}
.odd {
background-color: #55bbff;
color: #223311;
}
.even {
background-color: #ee7756;
color: #551133;
}
.code {
--index: calc(var(--layer) - 1);
padding-top: calc(var(--index) * 0.15em);
filter:
hue-rotate(calc(var(--index) * 25deg))
saturate(calc(100% - (var(--index) * 2%)))
brightness(calc(100% - (var(--index) * 1.5%)));
}
.annotation {
color: #4444ff;
font-family: monospace;
font-style: italic;
display: none;
-webkit-user-select: none;
}
body:active .annotation {
/* requires holding mouse down anywhere on the page */
display: inline-block;
}
span:hover .annotation {
/* requires hover over a span ONLY on its first line */
display: inline-block;
}
</style>
</head>
<body>
<div class="code" style="counter-reset: line 16"><span class="line"><span><span class="code even" style="--layer: 1" title="18:8-18:9: @0[2]: _3 = _1
18:8-18:14: @0[3]: _2 = Ne(move _3, const 0_u32)"><span class="annotation">@0⦊</span>fn unused_func(mut a: u32) {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="18:8-18:9: @0[2]: _3 = _1
18:8-18:14: @0[3]: _2 = Ne(move _3, const 0_u32)"> if a != 0<span class="annotation">⦉@0</span></span></span><span class="code" style="--layer: 0"> </span><span><span class="code odd" style="--layer: 1" title="19:9-19:15: @1[0]: _4 = CheckedAdd(_1, const 1_u32)
19:9-19:15: @3[0]: _1 = move (_4.0: u32)
18:15-20:6: @3[1]: _0 = const ()"><span class="annotation">@1,3⦊</span>{</span></span>
<span class="line"><span class="code odd" style="--layer: 1" title="19:9-19:15: @1[0]: _4 = CheckedAdd(_1, const 1_u32)
19:9-19:15: @3[0]: _1 = move (_4.0: u32)
18:15-20:6: @3[1]: _0 = const ()"> a += 1;</span></span>
<span class="line"><span class="code odd" style="--layer: 1" title="19:9-19:15: @1[0]: _4 = CheckedAdd(_1, const 1_u32)
19:9-19:15: @3[0]: _1 = move (_4.0: u32)
18:15-20:6: @3[1]: _0 = const ()"> }<span class="annotation">⦉@1,3</span></span></span><span><span class="code even" style="--layer: 1" title="20:6-20:6: @2[0]: _0 = const ()"><span class="annotation">@2⦊</span><span class="annotation">⦉@2</span></span></span><span class="code" style="--layer: 0"></span></span>
<span class="line"><span class="code" style="--layer: 0">}</span><span><span class="code odd" style="--layer: 1" title="21:2-21:2: @4.Return: return"><span class="annotation">@4⦊</span><span class="annotation">⦉@4</span></span></span></span></div>
</body>
</html>

View file

@ -0,0 +1,86 @@
<!DOCTYPE html>
<!--
Preview this file as rendered HTML from the github source at:
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_func2.-------.InstrumentCoverage.0.html
For revisions in Pull Requests (PR):
* Replace "rust-lang" with the github PR author
* Replace "master" with the PR branch name
-->
<html>
<head>
<title>unused.unused_func2 - Coverage Spans</title>
<style>
.line {
counter-increment: line;
}
.line:before {
content: counter(line) ": ";
font-family: Menlo, Monaco, monospace;
font-style: italic;
width: 3.8em;
display: inline-block;
text-align: right;
filter: opacity(50%);
-webkit-user-select: none;
}
.code {
color: #dddddd;
background-color: #222222;
font-family: Menlo, Monaco, monospace;
line-height: 1.4em;
border-bottom: 2px solid #222222;
white-space: pre;
display: inline-block;
}
.odd {
background-color: #55bbff;
color: #223311;
}
.even {
background-color: #ee7756;
color: #551133;
}
.code {
--index: calc(var(--layer) - 1);
padding-top: calc(var(--index) * 0.15em);
filter:
hue-rotate(calc(var(--index) * 25deg))
saturate(calc(100% - (var(--index) * 2%)))
brightness(calc(100% - (var(--index) * 1.5%)));
}
.annotation {
color: #4444ff;
font-family: monospace;
font-style: italic;
display: none;
-webkit-user-select: none;
}
body:active .annotation {
/* requires holding mouse down anywhere on the page */
display: inline-block;
}
span:hover .annotation {
/* requires hover over a span ONLY on its first line */
display: inline-block;
}
</style>
</head>
<body>
<div class="code" style="counter-reset: line 22"><span class="line"><span><span class="code even" style="--layer: 1" title="24:8-24:9: @0[2]: _3 = _1
24:8-24:14: @0[3]: _2 = Ne(move _3, const 0_u32)"><span class="annotation">@0⦊</span>fn unused_func2(mut a: u32) {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="24:8-24:9: @0[2]: _3 = _1
24:8-24:14: @0[3]: _2 = Ne(move _3, const 0_u32)"> if a != 0<span class="annotation">⦉@0</span></span></span><span class="code" style="--layer: 0"> </span><span><span class="code odd" style="--layer: 1" title="25:9-25:15: @1[0]: _4 = CheckedAdd(_1, const 1_u32)
25:9-25:15: @3[0]: _1 = move (_4.0: u32)
24:15-26:6: @3[1]: _0 = const ()"><span class="annotation">@1,3⦊</span>{</span></span>
<span class="line"><span class="code odd" style="--layer: 1" title="25:9-25:15: @1[0]: _4 = CheckedAdd(_1, const 1_u32)
25:9-25:15: @3[0]: _1 = move (_4.0: u32)
24:15-26:6: @3[1]: _0 = const ()"> a += 1;</span></span>
<span class="line"><span class="code odd" style="--layer: 1" title="25:9-25:15: @1[0]: _4 = CheckedAdd(_1, const 1_u32)
25:9-25:15: @3[0]: _1 = move (_4.0: u32)
24:15-26:6: @3[1]: _0 = const ()"> }<span class="annotation">⦉@1,3</span></span></span><span><span class="code even" style="--layer: 1" title="26:6-26:6: @2[0]: _0 = const ()"><span class="annotation">@2⦊</span><span class="annotation">⦉@2</span></span></span><span class="code" style="--layer: 0"></span></span>
<span class="line"><span class="code" style="--layer: 0">}</span><span><span class="code odd" style="--layer: 1" title="27:2-27:2: @4.Return: return"><span class="annotation">@4⦊</span><span class="annotation">⦉@4</span></span></span></span></div>
</body>
</html>

View file

@ -0,0 +1,86 @@
<!DOCTYPE html>
<!--
Preview this file as rendered HTML from the github source at:
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_func3.-------.InstrumentCoverage.0.html
For revisions in Pull Requests (PR):
* Replace "rust-lang" with the github PR author
* Replace "master" with the PR branch name
-->
<html>
<head>
<title>unused.unused_func3 - Coverage Spans</title>
<style>
.line {
counter-increment: line;
}
.line:before {
content: counter(line) ": ";
font-family: Menlo, Monaco, monospace;
font-style: italic;
width: 3.8em;
display: inline-block;
text-align: right;
filter: opacity(50%);
-webkit-user-select: none;
}
.code {
color: #dddddd;
background-color: #222222;
font-family: Menlo, Monaco, monospace;
line-height: 1.4em;
border-bottom: 2px solid #222222;
white-space: pre;
display: inline-block;
}
.odd {
background-color: #55bbff;
color: #223311;
}
.even {
background-color: #ee7756;
color: #551133;
}
.code {
--index: calc(var(--layer) - 1);
padding-top: calc(var(--index) * 0.15em);
filter:
hue-rotate(calc(var(--index) * 25deg))
saturate(calc(100% - (var(--index) * 2%)))
brightness(calc(100% - (var(--index) * 1.5%)));
}
.annotation {
color: #4444ff;
font-family: monospace;
font-style: italic;
display: none;
-webkit-user-select: none;
}
body:active .annotation {
/* requires holding mouse down anywhere on the page */
display: inline-block;
}
span:hover .annotation {
/* requires hover over a span ONLY on its first line */
display: inline-block;
}
</style>
</head>
<body>
<div class="code" style="counter-reset: line 28"><span class="line"><span><span class="code even" style="--layer: 1" title="30:8-30:9: @0[2]: _3 = _1
30:8-30:14: @0[3]: _2 = Ne(move _3, const 0_u32)"><span class="annotation">@0⦊</span>fn unused_func3(mut a: u32) {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="30:8-30:9: @0[2]: _3 = _1
30:8-30:14: @0[3]: _2 = Ne(move _3, const 0_u32)"> if a != 0<span class="annotation">⦉@0</span></span></span><span class="code" style="--layer: 0"> </span><span><span class="code odd" style="--layer: 1" title="31:9-31:15: @1[0]: _4 = CheckedAdd(_1, const 1_u32)
31:9-31:15: @3[0]: _1 = move (_4.0: u32)
30:15-32:6: @3[1]: _0 = const ()"><span class="annotation">@1,3⦊</span>{</span></span>
<span class="line"><span class="code odd" style="--layer: 1" title="31:9-31:15: @1[0]: _4 = CheckedAdd(_1, const 1_u32)
31:9-31:15: @3[0]: _1 = move (_4.0: u32)
30:15-32:6: @3[1]: _0 = const ()"> a += 1;</span></span>
<span class="line"><span class="code odd" style="--layer: 1" title="31:9-31:15: @1[0]: _4 = CheckedAdd(_1, const 1_u32)
31:9-31:15: @3[0]: _1 = move (_4.0: u32)
30:15-32:6: @3[1]: _0 = const ()"> }<span class="annotation">⦉@1,3</span></span></span><span><span class="code even" style="--layer: 1" title="32:6-32:6: @2[0]: _0 = const ()"><span class="annotation">@2⦊</span><span class="annotation">⦉@2</span></span></span><span class="code" style="--layer: 0"></span></span>
<span class="line"><span class="code" style="--layer: 0">}</span><span><span class="code odd" style="--layer: 1" title="33:2-33:2: @4.Return: return"><span class="annotation">@4⦊</span><span class="annotation">⦉@4</span></span></span></span></div>
</body>
</html>

View file

@ -0,0 +1,87 @@
<!DOCTYPE html>
<!--
Preview this file as rendered HTML from the github source at:
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_template_func.-------.InstrumentCoverage.0.html
For revisions in Pull Requests (PR):
* Replace "rust-lang" with the github PR author
* Replace "master" with the PR branch name
-->
<html>
<head>
<title>unused.unused_template_func - Coverage Spans</title>
<style>
.line {
counter-increment: line;
}
.line:before {
content: counter(line) ": ";
font-family: Menlo, Monaco, monospace;
font-style: italic;
width: 3.8em;
display: inline-block;
text-align: right;
filter: opacity(50%);
-webkit-user-select: none;
}
.code {
color: #dddddd;
background-color: #222222;
font-family: Menlo, Monaco, monospace;
line-height: 1.4em;
border-bottom: 2px solid #222222;
white-space: pre;
display: inline-block;
}
.odd {
background-color: #55bbff;
color: #223311;
}
.even {
background-color: #ee7756;
color: #551133;
}
.code {
--index: calc(var(--layer) - 1);
padding-top: calc(var(--index) * 0.15em);
filter:
hue-rotate(calc(var(--index) * 25deg))
saturate(calc(100% - (var(--index) * 2%)))
brightness(calc(100% - (var(--index) * 1.5%)));
}
.annotation {
color: #4444ff;
font-family: monospace;
font-style: italic;
display: none;
-webkit-user-select: none;
}
body:active .annotation {
/* requires holding mouse down anywhere on the page */
display: inline-block;
}
span:hover .annotation {
/* requires hover over a span ONLY on its first line */
display: inline-block;
}
</style>
</head>
<body>
<div class="code" style="counter-reset: line 8"><span class="line"><span><span class="code even" style="--layer: 1" title="10:17-10:18: @0[1]: _2 = const 0_i32
10:9-10:14: @0[2]: FakeRead(ForLet, _2)"><span class="annotation">@0⦊</span>fn unused_template_func&lt;T&gt;(x: T) {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="10:17-10:18: @0[1]: _2 = const 0_i32
10:9-10:14: @0[2]: FakeRead(ForLet, _2)"> let mut i = 0<span class="annotation">⦉@0</span></span></span><span class="code" style="--layer: 0">;</span></span>
<span class="line"><span class="code" style="--layer: 0"> while </span><span><span class="code odd" style="--layer: 1" title="11:11-11:12: @2[2]: _5 = _2
11:11-11:17: @2[3]: _4 = Lt(move _5, const 10_i32)
11:11-11:17: @2[5]: FakeRead(ForMatchedPlace, _4)"><span class="annotation">@1,2⦊</span>i &lt; 10<span class="annotation">⦉@1,2</span></span></span><span class="code" style="--layer: 0"> {</span></span>
<span class="line"><span class="code" style="--layer: 0"> </span><span><span class="code even" style="--layer: 1" title="12:9-12:10: @5[3]: _8 = _2
12:9-12:15: @5[4]: _7 = Ne(move _8, const 0_i32)"><span class="annotation">@3,5⦊</span>i != 0<span class="annotation">⦉@3,5</span></span></span><span class="code" style="--layer: 0"> || </span><span><span class="code odd" style="--layer: 1" title="12:19-12:20: @8[2]: _10 = _2
12:19-12:25: @8[3]: _9 = Ne(move _10, const 0_i32)"><span class="annotation">@8⦊</span>i != 0<span class="annotation">⦉@8</span></span></span><span class="code" style="--layer: 0">;</span></span>
<span class="line"><span class="code" style="--layer: 0"> </span><span><span class="code even" style="--layer: 1" title="13:9-13:15: @9[3]: _11 = CheckedAdd(_2, const 1_i32)
13:9-13:15: @10[0]: _2 = move (_11.0: i32)"><span class="annotation">@9,10⦊</span>i += 1<span class="annotation">⦉@9,10</span></span></span><span class="code" style="--layer: 0">;</span></span>
<span class="line"><span class="code" style="--layer: 0"> }</span></span>
<span class="line"><span class="code" style="--layer: 0">}</span><span><span class="code odd" style="--layer: 1" title="15:2-15:2: @11.Return: return"><span class="annotation">@4,11⦊</span><span class="annotation">⦉@4,11</span></span></span></span></div>
</body>
</html>

View file

@ -0,0 +1,115 @@
<!DOCTYPE html>
<!--
Preview this file as rendered HTML from the github source at:
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.unused_function.-------.InstrumentCoverage.0.html
For revisions in Pull Requests (PR):
* Replace "rust-lang" with the github PR author
* Replace "master" with the PR branch name
-->
<html>
<head>
<title>used_inline_crate.unused_function - Coverage Spans</title>
<style>
.line {
counter-increment: line;
}
.line:before {
content: counter(line) ": ";
font-family: Menlo, Monaco, monospace;
font-style: italic;
width: 3.8em;
display: inline-block;
text-align: right;
filter: opacity(50%);
-webkit-user-select: none;
}
.code {
color: #dddddd;
background-color: #222222;
font-family: Menlo, Monaco, monospace;
line-height: 1.4em;
border-bottom: 2px solid #222222;
white-space: pre;
display: inline-block;
}
.odd {
background-color: #55bbff;
color: #223311;
}
.even {
background-color: #ee7756;
color: #551133;
}
.code {
--index: calc(var(--layer) - 1);
padding-top: calc(var(--index) * 0.15em);
filter:
hue-rotate(calc(var(--index) * 25deg))
saturate(calc(100% - (var(--index) * 2%)))
brightness(calc(100% - (var(--index) * 1.5%)));
}
.annotation {
color: #4444ff;
font-family: monospace;
font-style: italic;
display: none;
-webkit-user-select: none;
}
body:active .annotation {
/* requires holding mouse down anywhere on the page */
display: inline-block;
}
span:hover .annotation {
/* requires hover over a span ONLY on its first line */
display: inline-block;
}
</style>
</head>
<body>
<div class="code" style="counter-reset: line 64"><span class="line"><span><span class="code even" style="--layer: 1" title="66:19-66:35: @0.Call: _4 = std::env::args() -&gt; [return: bb1, unwind: bb8]
66:19-66:35: @1[0]: _3 = &amp;_4
66:19-66:41: @1.Call: _2 = &lt;std::env::Args as std::iter::ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb7]
66:19-66:46: @2[1]: _1 = Eq(move _2, const 1_usize)
66:9-66:16: @2[3]: FakeRead(ForLet, _1)
67:25-67:26: @3[2]: _5 = const 2_i32
67:9-67:22: @3[3]: FakeRead(ForLet, _5)
68:9-68:16: @3[6]: _7 = _1
68:8-68:16: @3[7]: _6 = Not(move _7)"><span class="annotation">@0,1,2,3⦊</span>pub fn unused_function() {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="66:19-66:35: @0.Call: _4 = std::env::args() -&gt; [return: bb1, unwind: bb8]
66:19-66:35: @1[0]: _3 = &amp;_4
66:19-66:41: @1.Call: _2 = &lt;std::env::Args as std::iter::ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb7]
66:19-66:46: @2[1]: _1 = Eq(move _2, const 1_usize)
66:9-66:16: @2[3]: FakeRead(ForLet, _1)
67:25-67:26: @3[2]: _5 = const 2_i32
67:9-67:22: @3[3]: FakeRead(ForLet, _5)
68:9-68:16: @3[6]: _7 = _1
68:8-68:16: @3[7]: _6 = Not(move _7)"> let is_true = std::env::args().len() == 1;</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="66:19-66:35: @0.Call: _4 = std::env::args() -&gt; [return: bb1, unwind: bb8]
66:19-66:35: @1[0]: _3 = &amp;_4
66:19-66:41: @1.Call: _2 = &lt;std::env::Args as std::iter::ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb7]
66:19-66:46: @2[1]: _1 = Eq(move _2, const 1_usize)
66:9-66:16: @2[3]: FakeRead(ForLet, _1)
67:25-67:26: @3[2]: _5 = const 2_i32
67:9-67:22: @3[3]: FakeRead(ForLet, _5)
68:9-68:16: @3[6]: _7 = _1
68:8-68:16: @3[7]: _6 = Not(move _7)"> let mut countdown = 2;</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="66:19-66:35: @0.Call: _4 = std::env::args() -&gt; [return: bb1, unwind: bb8]
66:19-66:35: @1[0]: _3 = &amp;_4
66:19-66:41: @1.Call: _2 = &lt;std::env::Args as std::iter::ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb7]
66:19-66:46: @2[1]: _1 = Eq(move _2, const 1_usize)
66:9-66:16: @2[3]: FakeRead(ForLet, _1)
67:25-67:26: @3[2]: _5 = const 2_i32
67:9-67:22: @3[3]: FakeRead(ForLet, _5)
68:9-68:16: @3[6]: _7 = _1
68:8-68:16: @3[7]: _6 = Not(move _7)"> if !is_true<span class="annotation">⦉@0,1,2,3</span></span></span><span class="code" style="--layer: 0"> </span><span><span class="code odd" style="--layer: 1" title="69:9-69:23: @4[0]: _5 = const 20_i32
68:17-70:6: @4[1]: _0 = const ()"><span class="annotation">@4⦊</span>{</span></span>
<span class="line"><span class="code odd" style="--layer: 1" title="69:9-69:23: @4[0]: _5 = const 20_i32
68:17-70:6: @4[1]: _0 = const ()"> countdown = 20;</span></span>
<span class="line"><span class="code odd" style="--layer: 1" title="69:9-69:23: @4[0]: _5 = const 20_i32
68:17-70:6: @4[1]: _0 = const ()"> }<span class="annotation">⦉@4</span></span></span><span><span class="code even" style="--layer: 1" title="70:6-70:6: @5[0]: _0 = const ()"><span class="annotation">@5⦊</span><span class="annotation">⦉@5</span></span></span><span class="code" style="--layer: 0"></span></span>
<span class="line"><span class="code" style="--layer: 0">}</span><span><span class="code odd" style="--layer: 1" title="71:2-71:2: @6.Return: return"><span class="annotation">@6⦊</span><span class="annotation">⦉@6</span></span></span></span></div>
</body>
</html>

View file

@ -0,0 +1,133 @@
<!DOCTYPE html>
<!--
Preview this file as rendered HTML from the github source at:
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.unused_generic_function.-------.InstrumentCoverage.0.html
For revisions in Pull Requests (PR):
* Replace "rust-lang" with the github PR author
* Replace "master" with the PR branch name
-->
<html>
<head>
<title>used_inline_crate.unused_generic_function - Coverage Spans</title>
<style>
.line {
counter-increment: line;
}
.line:before {
content: counter(line) ": ";
font-family: Menlo, Monaco, monospace;
font-style: italic;
width: 3.8em;
display: inline-block;
text-align: right;
filter: opacity(50%);
-webkit-user-select: none;
}
.code {
color: #dddddd;
background-color: #222222;
font-family: Menlo, Monaco, monospace;
line-height: 1.4em;
border-bottom: 2px solid #222222;
white-space: pre;
display: inline-block;
}
.odd {
background-color: #55bbff;
color: #223311;
}
.even {
background-color: #ee7756;
color: #551133;
}
.code {
--index: calc(var(--layer) - 1);
padding-top: calc(var(--index) * 0.15em);
filter:
hue-rotate(calc(var(--index) * 25deg))
saturate(calc(100% - (var(--index) * 2%)))
brightness(calc(100% - (var(--index) * 1.5%)));
}
.annotation {
color: #4444ff;
font-family: monospace;
font-style: italic;
display: none;
-webkit-user-select: none;
}
body:active .annotation {
/* requires holding mouse down anywhere on the page */
display: inline-block;
}
span:hover .annotation {
/* requires hover over a span ONLY on its first line */
display: inline-block;
}
</style>
</head>
<body>
<div class="code" style="counter-reset: line 59"><span class="line"><span><span class="code even" style="--layer: 1" title="61:14-61:49: @0[6]: _19 = const unused_generic_function::&lt;T&gt;::promoted[0]
61:14-61:49: @0[7]: _7 = &amp;(*_19)
61:14-61:49: @0[8]: _6 = &amp;(*_7)
61:14-61:49: @0[9]: _5 = move _6 as &amp;[&amp;str] (Pointer(Unsize))
61:51-61:54: @0[17]: _14 = &amp;_1
61:5-61:56: @0[18]: _13 = (move _14,)
61:5-61:56: @0[20]: FakeRead(ForMatchedPlace, _13)
61:5-61:56: @0[22]: _15 = (_13.0: &amp;T)
61:5-61:56: @0[25]: _17 = &amp;(*_15)
61:5-61:56: @0[27]: _18 = &lt;T as std::fmt::Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r T, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
61:5-61:56: @0.Call: _16 = std::fmt::ArgumentV1::new::&lt;T&gt;(move _17, move _18) -&gt; [return: bb1, unwind: bb5]
61:5-61:56: @1[2]: _12 = [move _16]
61:5-61:56: @1[5]: _11 = &amp;_12
61:5-61:56: @1[6]: _10 = &amp;(*_11)
61:5-61:56: @1[7]: _9 = move _10 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
61:5-61:56: @1.Call: _4 = std::fmt::Arguments::new_v1(move _5, move _9) -&gt; [return: bb2, unwind: bb5]
61:5-61:56: @2.Call: _3 = std::io::_print(move _4) -&gt; [return: bb3, unwind: bb5]
61:5-61:56: @3[6]: _2 = const ()
60:50-62:2: @3[8]: _0 = const ()
62:2-62:2: @4.Return: return"><span class="annotation">@0,1,2,3,4⦊</span>pub fn unused_generic_function&lt;T: Debug&gt;(arg: T) {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="61:14-61:49: @0[6]: _19 = const unused_generic_function::&lt;T&gt;::promoted[0]
61:14-61:49: @0[7]: _7 = &amp;(*_19)
61:14-61:49: @0[8]: _6 = &amp;(*_7)
61:14-61:49: @0[9]: _5 = move _6 as &amp;[&amp;str] (Pointer(Unsize))
61:51-61:54: @0[17]: _14 = &amp;_1
61:5-61:56: @0[18]: _13 = (move _14,)
61:5-61:56: @0[20]: FakeRead(ForMatchedPlace, _13)
61:5-61:56: @0[22]: _15 = (_13.0: &amp;T)
61:5-61:56: @0[25]: _17 = &amp;(*_15)
61:5-61:56: @0[27]: _18 = &lt;T as std::fmt::Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r T, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
61:5-61:56: @0.Call: _16 = std::fmt::ArgumentV1::new::&lt;T&gt;(move _17, move _18) -&gt; [return: bb1, unwind: bb5]
61:5-61:56: @1[2]: _12 = [move _16]
61:5-61:56: @1[5]: _11 = &amp;_12
61:5-61:56: @1[6]: _10 = &amp;(*_11)
61:5-61:56: @1[7]: _9 = move _10 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
61:5-61:56: @1.Call: _4 = std::fmt::Arguments::new_v1(move _5, move _9) -&gt; [return: bb2, unwind: bb5]
61:5-61:56: @2.Call: _3 = std::io::_print(move _4) -&gt; [return: bb3, unwind: bb5]
61:5-61:56: @3[6]: _2 = const ()
60:50-62:2: @3[8]: _0 = const ()
62:2-62:2: @4.Return: return"> println!("unused_generic_function with {:?}", arg);</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="61:14-61:49: @0[6]: _19 = const unused_generic_function::&lt;T&gt;::promoted[0]
61:14-61:49: @0[7]: _7 = &amp;(*_19)
61:14-61:49: @0[8]: _6 = &amp;(*_7)
61:14-61:49: @0[9]: _5 = move _6 as &amp;[&amp;str] (Pointer(Unsize))
61:51-61:54: @0[17]: _14 = &amp;_1
61:5-61:56: @0[18]: _13 = (move _14,)
61:5-61:56: @0[20]: FakeRead(ForMatchedPlace, _13)
61:5-61:56: @0[22]: _15 = (_13.0: &amp;T)
61:5-61:56: @0[25]: _17 = &amp;(*_15)
61:5-61:56: @0[27]: _18 = &lt;T as std::fmt::Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r T, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
61:5-61:56: @0.Call: _16 = std::fmt::ArgumentV1::new::&lt;T&gt;(move _17, move _18) -&gt; [return: bb1, unwind: bb5]
61:5-61:56: @1[2]: _12 = [move _16]
61:5-61:56: @1[5]: _11 = &amp;_12
61:5-61:56: @1[6]: _10 = &amp;(*_11)
61:5-61:56: @1[7]: _9 = move _10 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
61:5-61:56: @1.Call: _4 = std::fmt::Arguments::new_v1(move _5, move _9) -&gt; [return: bb2, unwind: bb5]
61:5-61:56: @2.Call: _3 = std::io::_print(move _4) -&gt; [return: bb3, unwind: bb5]
61:5-61:56: @3[6]: _2 = const ()
60:50-62:2: @3[8]: _0 = const ()
62:2-62:2: @4.Return: return">}<span class="annotation">⦉@0,1,2,3,4</span></span></span></span></div>
</body>
</html>

View file

@ -0,0 +1,115 @@
<!DOCTYPE html>
<!--
Preview this file as rendered HTML from the github source at:
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.unused_private_function.-------.InstrumentCoverage.0.html
For revisions in Pull Requests (PR):
* Replace "rust-lang" with the github PR author
* Replace "master" with the PR branch name
-->
<html>
<head>
<title>used_inline_crate.unused_private_function - Coverage Spans</title>
<style>
.line {
counter-increment: line;
}
.line:before {
content: counter(line) ": ";
font-family: Menlo, Monaco, monospace;
font-style: italic;
width: 3.8em;
display: inline-block;
text-align: right;
filter: opacity(50%);
-webkit-user-select: none;
}
.code {
color: #dddddd;
background-color: #222222;
font-family: Menlo, Monaco, monospace;
line-height: 1.4em;
border-bottom: 2px solid #222222;
white-space: pre;
display: inline-block;
}
.odd {
background-color: #55bbff;
color: #223311;
}
.even {
background-color: #ee7756;
color: #551133;
}
.code {
--index: calc(var(--layer) - 1);
padding-top: calc(var(--index) * 0.15em);
filter:
hue-rotate(calc(var(--index) * 25deg))
saturate(calc(100% - (var(--index) * 2%)))
brightness(calc(100% - (var(--index) * 1.5%)));
}
.annotation {
color: #4444ff;
font-family: monospace;
font-style: italic;
display: none;
-webkit-user-select: none;
}
body:active .annotation {
/* requires holding mouse down anywhere on the page */
display: inline-block;
}
span:hover .annotation {
/* requires hover over a span ONLY on its first line */
display: inline-block;
}
</style>
</head>
<body>
<div class="code" style="counter-reset: line 73"><span class="line"><span><span class="code even" style="--layer: 1" title="75:19-75:35: @0.Call: _4 = std::env::args() -&gt; [return: bb1, unwind: bb8]
75:19-75:35: @1[0]: _3 = &amp;_4
75:19-75:41: @1.Call: _2 = &lt;std::env::Args as std::iter::ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb7]
75:19-75:46: @2[1]: _1 = Eq(move _2, const 1_usize)
75:9-75:16: @2[3]: FakeRead(ForLet, _1)
76:25-76:26: @3[2]: _5 = const 2_i32
76:9-76:22: @3[3]: FakeRead(ForLet, _5)
77:9-77:16: @3[6]: _7 = _1
77:8-77:16: @3[7]: _6 = Not(move _7)"><span class="annotation">@0,1,2,3⦊</span>fn unused_private_function() {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="75:19-75:35: @0.Call: _4 = std::env::args() -&gt; [return: bb1, unwind: bb8]
75:19-75:35: @1[0]: _3 = &amp;_4
75:19-75:41: @1.Call: _2 = &lt;std::env::Args as std::iter::ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb7]
75:19-75:46: @2[1]: _1 = Eq(move _2, const 1_usize)
75:9-75:16: @2[3]: FakeRead(ForLet, _1)
76:25-76:26: @3[2]: _5 = const 2_i32
76:9-76:22: @3[3]: FakeRead(ForLet, _5)
77:9-77:16: @3[6]: _7 = _1
77:8-77:16: @3[7]: _6 = Not(move _7)"> let is_true = std::env::args().len() == 1;</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="75:19-75:35: @0.Call: _4 = std::env::args() -&gt; [return: bb1, unwind: bb8]
75:19-75:35: @1[0]: _3 = &amp;_4
75:19-75:41: @1.Call: _2 = &lt;std::env::Args as std::iter::ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb7]
75:19-75:46: @2[1]: _1 = Eq(move _2, const 1_usize)
75:9-75:16: @2[3]: FakeRead(ForLet, _1)
76:25-76:26: @3[2]: _5 = const 2_i32
76:9-76:22: @3[3]: FakeRead(ForLet, _5)
77:9-77:16: @3[6]: _7 = _1
77:8-77:16: @3[7]: _6 = Not(move _7)"> let mut countdown = 2;</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="75:19-75:35: @0.Call: _4 = std::env::args() -&gt; [return: bb1, unwind: bb8]
75:19-75:35: @1[0]: _3 = &amp;_4
75:19-75:41: @1.Call: _2 = &lt;std::env::Args as std::iter::ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb7]
75:19-75:46: @2[1]: _1 = Eq(move _2, const 1_usize)
75:9-75:16: @2[3]: FakeRead(ForLet, _1)
76:25-76:26: @3[2]: _5 = const 2_i32
76:9-76:22: @3[3]: FakeRead(ForLet, _5)
77:9-77:16: @3[6]: _7 = _1
77:8-77:16: @3[7]: _6 = Not(move _7)"> if !is_true<span class="annotation">⦉@0,1,2,3</span></span></span><span class="code" style="--layer: 0"> </span><span><span class="code odd" style="--layer: 1" title="78:9-78:23: @4[0]: _5 = const 20_i32
77:17-79:6: @4[1]: _0 = const ()"><span class="annotation">@4⦊</span>{</span></span>
<span class="line"><span class="code odd" style="--layer: 1" title="78:9-78:23: @4[0]: _5 = const 20_i32
77:17-79:6: @4[1]: _0 = const ()"> countdown = 20;</span></span>
<span class="line"><span class="code odd" style="--layer: 1" title="78:9-78:23: @4[0]: _5 = const 20_i32
77:17-79:6: @4[1]: _0 = const ()"> }<span class="annotation">⦉@4</span></span></span><span><span class="code even" style="--layer: 1" title="79:6-79:6: @5[0]: _0 = const ()"><span class="annotation">@5⦊</span><span class="annotation">⦉@5</span></span></span><span class="code" style="--layer: 0"></span></span>
<span class="line"><span class="code" style="--layer: 0">}</span><span><span class="code odd" style="--layer: 1" title="80:2-80:2: @6.Return: return"><span class="annotation">@6⦊</span><span class="annotation">⦉@6</span></span></span></span></div>
</body>
</html>

View file

@ -0,0 +1,190 @@
<!DOCTYPE html>
<!--
Preview this file as rendered HTML from the github source at:
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.use_this_lib_crate.-------.InstrumentCoverage.0.html
For revisions in Pull Requests (PR):
* Replace "rust-lang" with the github PR author
* Replace "master" with the PR branch name
-->
<html>
<head>
<title>used_inline_crate.use_this_lib_crate - Coverage Spans</title>
<style>
.line {
counter-increment: line;
}
.line:before {
content: counter(line) ": ";
font-family: Menlo, Monaco, monospace;
font-style: italic;
width: 3.8em;
display: inline-block;
text-align: right;
filter: opacity(50%);
-webkit-user-select: none;
}
.code {
color: #dddddd;
background-color: #222222;
font-family: Menlo, Monaco, monospace;
line-height: 1.4em;
border-bottom: 2px solid #222222;
white-space: pre;
display: inline-block;
}
.odd {
background-color: #55bbff;
color: #223311;
}
.even {
background-color: #ee7756;
color: #551133;
}
.code {
--index: calc(var(--layer) - 1);
padding-top: calc(var(--index) * 0.15em);
filter:
hue-rotate(calc(var(--index) * 25deg))
saturate(calc(100% - (var(--index) * 2%)))
brightness(calc(100% - (var(--index) * 1.5%)));
}
.annotation {
color: #4444ff;
font-family: monospace;
font-style: italic;
display: none;
-webkit-user-select: none;
}
body:active .annotation {
/* requires holding mouse down anywhere on the page */
display: inline-block;
}
span:hover .annotation {
/* requires hover over a span ONLY on its first line */
display: inline-block;
}
</style>
</head>
<body>
<div class="code" style="counter-reset: line 81"><span class="line"><span><span class="code even" style="--layer: 1" title="83:5-83:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb13]
84:5-86:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb13]
87:20-87:36: @2[5]: _6 = Box([i32; 4])
87:20-87:36: @2[6]: (*_6) = [const 5_i32, const 6_i32, const 7_i32, const 8_i32]
87:20-87:36: @2[7]: _5 = move _6
87:20-87:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
87:20-87:36: @4.Call: _3 = std::slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb12]
87:9-87:17: @5[1]: FakeRead(ForLet, _3)
88:52-88:60: @5[4]: _8 = move _3
88:5-88:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;std::vec::Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb9]
89:5-89:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb7, unwind: bb10]
82:25-90:2: @7[1]: _0 = const ()
90:2-90:2: @8.Return: return"><span class="annotation">@0,1,2,3,4,5,6,7,8⦊</span>fn use_this_lib_crate() {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="83:5-83:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb13]
84:5-86:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb13]
87:20-87:36: @2[5]: _6 = Box([i32; 4])
87:20-87:36: @2[6]: (*_6) = [const 5_i32, const 6_i32, const 7_i32, const 8_i32]
87:20-87:36: @2[7]: _5 = move _6
87:20-87:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
87:20-87:36: @4.Call: _3 = std::slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb12]
87:9-87:17: @5[1]: FakeRead(ForLet, _3)
88:52-88:60: @5[4]: _8 = move _3
88:5-88:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;std::vec::Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb9]
89:5-89:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb7, unwind: bb10]
82:25-90:2: @7[1]: _0 = const ()
90:2-90:2: @8.Return: return"> used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="83:5-83:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb13]
84:5-86:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb13]
87:20-87:36: @2[5]: _6 = Box([i32; 4])
87:20-87:36: @2[6]: (*_6) = [const 5_i32, const 6_i32, const 7_i32, const 8_i32]
87:20-87:36: @2[7]: _5 = move _6
87:20-87:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
87:20-87:36: @4.Call: _3 = std::slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb12]
87:9-87:17: @5[1]: FakeRead(ForLet, _3)
88:52-88:60: @5[4]: _8 = move _3
88:5-88:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;std::vec::Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb9]
89:5-89:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb7, unwind: bb10]
82:25-90:2: @7[1]: _0 = const ()
90:2-90:2: @8.Return: return"> used_with_same_type_from_bin_crate_and_lib_crate_generic_function(</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="83:5-83:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb13]
84:5-86:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb13]
87:20-87:36: @2[5]: _6 = Box([i32; 4])
87:20-87:36: @2[6]: (*_6) = [const 5_i32, const 6_i32, const 7_i32, const 8_i32]
87:20-87:36: @2[7]: _5 = move _6
87:20-87:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
87:20-87:36: @4.Call: _3 = std::slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb12]
87:9-87:17: @5[1]: FakeRead(ForLet, _3)
88:52-88:60: @5[4]: _8 = move _3
88:5-88:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;std::vec::Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb9]
89:5-89:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb7, unwind: bb10]
82:25-90:2: @7[1]: _0 = const ()
90:2-90:2: @8.Return: return"> "used from library used_crate.rs",</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="83:5-83:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb13]
84:5-86:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb13]
87:20-87:36: @2[5]: _6 = Box([i32; 4])
87:20-87:36: @2[6]: (*_6) = [const 5_i32, const 6_i32, const 7_i32, const 8_i32]
87:20-87:36: @2[7]: _5 = move _6
87:20-87:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
87:20-87:36: @4.Call: _3 = std::slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb12]
87:9-87:17: @5[1]: FakeRead(ForLet, _3)
88:52-88:60: @5[4]: _8 = move _3
88:5-88:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;std::vec::Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb9]
89:5-89:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb7, unwind: bb10]
82:25-90:2: @7[1]: _0 = const ()
90:2-90:2: @8.Return: return"> );</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="83:5-83:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb13]
84:5-86:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb13]
87:20-87:36: @2[5]: _6 = Box([i32; 4])
87:20-87:36: @2[6]: (*_6) = [const 5_i32, const 6_i32, const 7_i32, const 8_i32]
87:20-87:36: @2[7]: _5 = move _6
87:20-87:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
87:20-87:36: @4.Call: _3 = std::slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb12]
87:9-87:17: @5[1]: FakeRead(ForLet, _3)
88:52-88:60: @5[4]: _8 = move _3
88:5-88:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;std::vec::Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb9]
89:5-89:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb7, unwind: bb10]
82:25-90:2: @7[1]: _0 = const ()
90:2-90:2: @8.Return: return"> let some_vec = vec![5, 6, 7, 8];</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="83:5-83:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb13]
84:5-86:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb13]
87:20-87:36: @2[5]: _6 = Box([i32; 4])
87:20-87:36: @2[6]: (*_6) = [const 5_i32, const 6_i32, const 7_i32, const 8_i32]
87:20-87:36: @2[7]: _5 = move _6
87:20-87:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
87:20-87:36: @4.Call: _3 = std::slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb12]
87:9-87:17: @5[1]: FakeRead(ForLet, _3)
88:52-88:60: @5[4]: _8 = move _3
88:5-88:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;std::vec::Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb9]
89:5-89:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb7, unwind: bb10]
82:25-90:2: @7[1]: _0 = const ()
90:2-90:2: @8.Return: return"> used_only_from_this_lib_crate_generic_function(some_vec);</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="83:5-83:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb13]
84:5-86:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb13]
87:20-87:36: @2[5]: _6 = Box([i32; 4])
87:20-87:36: @2[6]: (*_6) = [const 5_i32, const 6_i32, const 7_i32, const 8_i32]
87:20-87:36: @2[7]: _5 = move _6
87:20-87:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
87:20-87:36: @4.Call: _3 = std::slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb12]
87:9-87:17: @5[1]: FakeRead(ForLet, _3)
88:52-88:60: @5[4]: _8 = move _3
88:5-88:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;std::vec::Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb9]
89:5-89:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb7, unwind: bb10]
82:25-90:2: @7[1]: _0 = const ()
90:2-90:2: @8.Return: return"> used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="83:5-83:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb13]
84:5-86:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb13]
87:20-87:36: @2[5]: _6 = Box([i32; 4])
87:20-87:36: @2[6]: (*_6) = [const 5_i32, const 6_i32, const 7_i32, const 8_i32]
87:20-87:36: @2[7]: _5 = move _6
87:20-87:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
87:20-87:36: @4.Call: _3 = std::slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb12]
87:9-87:17: @5[1]: FakeRead(ForLet, _3)
88:52-88:60: @5[4]: _8 = move _3
88:5-88:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;std::vec::Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb9]
89:5-89:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb7, unwind: bb10]
82:25-90:2: @7[1]: _0 = const ()
90:2-90:2: @8.Return: return">}<span class="annotation">⦉@0,1,2,3,4,5,6,7,8</span></span></span></span></div>
</body>
</html>

View file

@ -0,0 +1,133 @@
<!DOCTYPE html>
<!--
Preview this file as rendered HTML from the github source at:
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_from_bin_crate_and_lib_crate_generic_function.-------.InstrumentCoverage.0.html
For revisions in Pull Requests (PR):
* Replace "rust-lang" with the github PR author
* Replace "master" with the PR branch name
-->
<html>
<head>
<title>used_inline_crate.used_from_bin_crate_and_lib_crate_generic_function - Coverage Spans</title>
<style>
.line {
counter-increment: line;
}
.line:before {
content: counter(line) ": ";
font-family: Menlo, Monaco, monospace;
font-style: italic;
width: 3.8em;
display: inline-block;
text-align: right;
filter: opacity(50%);
-webkit-user-select: none;
}
.code {
color: #dddddd;
background-color: #222222;
font-family: Menlo, Monaco, monospace;
line-height: 1.4em;
border-bottom: 2px solid #222222;
white-space: pre;
display: inline-block;
}
.odd {
background-color: #55bbff;
color: #223311;
}
.even {
background-color: #ee7756;
color: #551133;
}
.code {
--index: calc(var(--layer) - 1);
padding-top: calc(var(--index) * 0.15em);
filter:
hue-rotate(calc(var(--index) * 25deg))
saturate(calc(100% - (var(--index) * 2%)))
brightness(calc(100% - (var(--index) * 1.5%)));
}
.annotation {
color: #4444ff;
font-family: monospace;
font-style: italic;
display: none;
-webkit-user-select: none;
}
body:active .annotation {
/* requires holding mouse down anywhere on the page */
display: inline-block;
}
span:hover .annotation {
/* requires hover over a span ONLY on its first line */
display: inline-block;
}
</style>
</head>
<body>
<div class="code" style="counter-reset: line 49"><span class="line"><span><span class="code even" style="--layer: 1" title="51:14-51:76: @0[6]: _19 = const used_from_bin_crate_and_lib_crate_generic_function::&lt;T&gt;::promoted[0]
51:14-51:76: @0[7]: _7 = &amp;(*_19)
51:14-51:76: @0[8]: _6 = &amp;(*_7)
51:14-51:76: @0[9]: _5 = move _6 as &amp;[&amp;str] (Pointer(Unsize))
51:78-51:81: @0[17]: _14 = &amp;_1
51:5-51:83: @0[18]: _13 = (move _14,)
51:5-51:83: @0[20]: FakeRead(ForMatchedPlace, _13)
51:5-51:83: @0[22]: _15 = (_13.0: &amp;T)
51:5-51:83: @0[25]: _17 = &amp;(*_15)
51:5-51:83: @0[27]: _18 = &lt;T as std::fmt::Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r T, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
51:5-51:83: @0.Call: _16 = std::fmt::ArgumentV1::new::&lt;T&gt;(move _17, move _18) -&gt; [return: bb1, unwind: bb5]
51:5-51:83: @1[2]: _12 = [move _16]
51:5-51:83: @1[5]: _11 = &amp;_12
51:5-51:83: @1[6]: _10 = &amp;(*_11)
51:5-51:83: @1[7]: _9 = move _10 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
51:5-51:83: @1.Call: _4 = std::fmt::Arguments::new_v1(move _5, move _9) -&gt; [return: bb2, unwind: bb5]
51:5-51:83: @2.Call: _3 = std::io::_print(move _4) -&gt; [return: bb3, unwind: bb5]
51:5-51:83: @3[6]: _2 = const ()
50:77-52:2: @3[8]: _0 = const ()
52:2-52:2: @4.Return: return"><span class="annotation">@0,1,2,3,4⦊</span>pub fn used_from_bin_crate_and_lib_crate_generic_function&lt;T: Debug&gt;(arg: T) {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="51:14-51:76: @0[6]: _19 = const used_from_bin_crate_and_lib_crate_generic_function::&lt;T&gt;::promoted[0]
51:14-51:76: @0[7]: _7 = &amp;(*_19)
51:14-51:76: @0[8]: _6 = &amp;(*_7)
51:14-51:76: @0[9]: _5 = move _6 as &amp;[&amp;str] (Pointer(Unsize))
51:78-51:81: @0[17]: _14 = &amp;_1
51:5-51:83: @0[18]: _13 = (move _14,)
51:5-51:83: @0[20]: FakeRead(ForMatchedPlace, _13)
51:5-51:83: @0[22]: _15 = (_13.0: &amp;T)
51:5-51:83: @0[25]: _17 = &amp;(*_15)
51:5-51:83: @0[27]: _18 = &lt;T as std::fmt::Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r T, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
51:5-51:83: @0.Call: _16 = std::fmt::ArgumentV1::new::&lt;T&gt;(move _17, move _18) -&gt; [return: bb1, unwind: bb5]
51:5-51:83: @1[2]: _12 = [move _16]
51:5-51:83: @1[5]: _11 = &amp;_12
51:5-51:83: @1[6]: _10 = &amp;(*_11)
51:5-51:83: @1[7]: _9 = move _10 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
51:5-51:83: @1.Call: _4 = std::fmt::Arguments::new_v1(move _5, move _9) -&gt; [return: bb2, unwind: bb5]
51:5-51:83: @2.Call: _3 = std::io::_print(move _4) -&gt; [return: bb3, unwind: bb5]
51:5-51:83: @3[6]: _2 = const ()
50:77-52:2: @3[8]: _0 = const ()
52:2-52:2: @4.Return: return"> println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="51:14-51:76: @0[6]: _19 = const used_from_bin_crate_and_lib_crate_generic_function::&lt;T&gt;::promoted[0]
51:14-51:76: @0[7]: _7 = &amp;(*_19)
51:14-51:76: @0[8]: _6 = &amp;(*_7)
51:14-51:76: @0[9]: _5 = move _6 as &amp;[&amp;str] (Pointer(Unsize))
51:78-51:81: @0[17]: _14 = &amp;_1
51:5-51:83: @0[18]: _13 = (move _14,)
51:5-51:83: @0[20]: FakeRead(ForMatchedPlace, _13)
51:5-51:83: @0[22]: _15 = (_13.0: &amp;T)
51:5-51:83: @0[25]: _17 = &amp;(*_15)
51:5-51:83: @0[27]: _18 = &lt;T as std::fmt::Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r T, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
51:5-51:83: @0.Call: _16 = std::fmt::ArgumentV1::new::&lt;T&gt;(move _17, move _18) -&gt; [return: bb1, unwind: bb5]
51:5-51:83: @1[2]: _12 = [move _16]
51:5-51:83: @1[5]: _11 = &amp;_12
51:5-51:83: @1[6]: _10 = &amp;(*_11)
51:5-51:83: @1[7]: _9 = move _10 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
51:5-51:83: @1.Call: _4 = std::fmt::Arguments::new_v1(move _5, move _9) -&gt; [return: bb2, unwind: bb5]
51:5-51:83: @2.Call: _3 = std::io::_print(move _4) -&gt; [return: bb3, unwind: bb5]
51:5-51:83: @3[6]: _2 = const ()
50:77-52:2: @3[8]: _0 = const ()
52:2-52:2: @4.Return: return">}<span class="annotation">⦉@0,1,2,3,4</span></span></span></span></div>
</body>
</html>

View file

@ -0,0 +1,110 @@
<!DOCTYPE html>
<!--
Preview this file as rendered HTML from the github source at:
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_function.-------.InstrumentCoverage.0.html
For revisions in Pull Requests (PR):
* Replace "rust-lang" with the github PR author
* Replace "master" with the PR branch name
-->
<html>
<head>
<title>used_inline_crate.used_function - Coverage Spans</title>
<style>
.line {
counter-increment: line;
}
.line:before {
content: counter(line) ": ";
font-family: Menlo, Monaco, monospace;
font-style: italic;
width: 3.8em;
display: inline-block;
text-align: right;
filter: opacity(50%);
-webkit-user-select: none;
}
.code {
color: #dddddd;
background-color: #222222;
font-family: Menlo, Monaco, monospace;
line-height: 1.4em;
border-bottom: 2px solid #222222;
white-space: pre;
display: inline-block;
}
.odd {
background-color: #55bbff;
color: #223311;
}
.even {
background-color: #ee7756;
color: #551133;
}
.code {
--index: calc(var(--layer) - 1);
padding-top: calc(var(--index) * 0.15em);
filter:
hue-rotate(calc(var(--index) * 25deg))
saturate(calc(100% - (var(--index) * 2%)))
brightness(calc(100% - (var(--index) * 1.5%)));
}
.annotation {
color: #4444ff;
font-family: monospace;
font-style: italic;
display: none;
-webkit-user-select: none;
}
body:active .annotation {
/* requires holding mouse down anywhere on the page */
display: inline-block;
}
span:hover .annotation {
/* requires hover over a span ONLY on its first line */
display: inline-block;
}
</style>
</head>
<body>
<div class="code" style="counter-reset: line 6"><span class="line"><span><span class="code even" style="--layer: 1"><span class="annotation">@0,1,2,3⦊</span>pub fn used_function() <span class="annotation">⦉@0,1,2,3</span></span></span><span class="code" style="--layer: 0">{</span></span>
<span class="line"><span class="code" style="--layer: 0"> // Initialize test constants in a way that cannot be determined at compile time, to ensure</span></span>
<span class="line"><span class="code" style="--layer: 0"> // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from</span></span>
<span class="line"><span class="code" style="--layer: 0"> // dependent conditions.</span></span>
<span class="line"><span class="code" style="--layer: 0"> let </span><span><span class="code even" style="--layer: 1" title="11:19-11:35: @0.Call: _4 = std::env::args() -&gt; [return: bb1, unwind: bb9]
11:19-11:35: @1[0]: _3 = &amp;_4
11:19-11:41: @1.Call: _2 = &lt;std::env::Args as std::iter::ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb8]
11:19-11:46: @2[1]: _1 = Eq(move _2, const 1_usize)
11:9-11:16: @2[3]: FakeRead(ForLet, _1)
12:25-12:26: @3[2]: _5 = const 0_i32
12:9-12:22: @3[3]: FakeRead(ForLet, _5)
13:8-13:15: @3[6]: _7 = _1"><span class="annotation">@0,1,2,3⦊</span>is_true = std::env::args().len() == 1;</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="11:19-11:35: @0.Call: _4 = std::env::args() -&gt; [return: bb1, unwind: bb9]
11:19-11:35: @1[0]: _3 = &amp;_4
11:19-11:41: @1.Call: _2 = &lt;std::env::Args as std::iter::ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb8]
11:19-11:46: @2[1]: _1 = Eq(move _2, const 1_usize)
11:9-11:16: @2[3]: FakeRead(ForLet, _1)
12:25-12:26: @3[2]: _5 = const 0_i32
12:9-12:22: @3[3]: FakeRead(ForLet, _5)
13:8-13:15: @3[6]: _7 = _1"> let mut countdown = 0;</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="11:19-11:35: @0.Call: _4 = std::env::args() -&gt; [return: bb1, unwind: bb9]
11:19-11:35: @1[0]: _3 = &amp;_4
11:19-11:41: @1.Call: _2 = &lt;std::env::Args as std::iter::ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb8]
11:19-11:46: @2[1]: _1 = Eq(move _2, const 1_usize)
11:9-11:16: @2[3]: FakeRead(ForLet, _1)
12:25-12:26: @3[2]: _5 = const 0_i32
12:9-12:22: @3[3]: FakeRead(ForLet, _5)
13:8-13:15: @3[6]: _7 = _1"> if is_true<span class="annotation">⦉@0,1,2,3</span></span></span><span class="code" style="--layer: 0"> </span><span><span class="code odd" style="--layer: 1" title="14:9-14:23: @4[0]: _5 = const 10_i32
13:16-15:6: @4[1]: _6 = const ()"><span class="annotation">@4⦊</span>{</span></span>
<span class="line"><span class="code odd" style="--layer: 1" title="14:9-14:23: @4[0]: _5 = const 10_i32
13:16-15:6: @4[1]: _6 = const ()"> countdown = 10;</span></span>
<span class="line"><span class="code odd" style="--layer: 1" title="14:9-14:23: @4[0]: _5 = const 10_i32
13:16-15:6: @4[1]: _6 = const ()"> }<span class="annotation">⦉@4</span></span></span><span><span class="code even" style="--layer: 1" title="15:6-15:6: @5[0]: _6 = const ()"><span class="annotation">@5⦊</span><span class="annotation">⦉@5</span></span></span><span class="code" style="--layer: 0"></span></span>
<span class="line"><span class="code" style="--layer: 0"> </span><span><span class="code odd" style="--layer: 1" title="16:5-16:25: @6.Call: _8 = use_this_lib_crate() -&gt; [return: bb7, unwind: bb9]
17:2-17:2: @7.Return: return"><span class="annotation">@6,7⦊</span>use_this_lib_crate();</span></span>
<span class="line"><span class="code odd" style="--layer: 1" title="16:5-16:25: @6.Call: _8 = use_this_lib_crate() -&gt; [return: bb7, unwind: bb9]
17:2-17:2: @7.Return: return">}<span class="annotation">⦉@6,7</span></span></span></span></div>
</body>
</html>

View file

@ -0,0 +1,110 @@
<!DOCTYPE html>
<!--
Preview this file as rendered HTML from the github source at:
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_inline_function.-------.InstrumentCoverage.0.html
For revisions in Pull Requests (PR):
* Replace "rust-lang" with the github PR author
* Replace "master" with the PR branch name
-->
<html>
<head>
<title>used_inline_crate.used_inline_function - Coverage Spans</title>
<style>
.line {
counter-increment: line;
}
.line:before {
content: counter(line) ": ";
font-family: Menlo, Monaco, monospace;
font-style: italic;
width: 3.8em;
display: inline-block;
text-align: right;
filter: opacity(50%);
-webkit-user-select: none;
}
.code {
color: #dddddd;
background-color: #222222;
font-family: Menlo, Monaco, monospace;
line-height: 1.4em;
border-bottom: 2px solid #222222;
white-space: pre;
display: inline-block;
}
.odd {
background-color: #55bbff;
color: #223311;
}
.even {
background-color: #ee7756;
color: #551133;
}
.code {
--index: calc(var(--layer) - 1);
padding-top: calc(var(--index) * 0.15em);
filter:
hue-rotate(calc(var(--index) * 25deg))
saturate(calc(100% - (var(--index) * 2%)))
brightness(calc(100% - (var(--index) * 1.5%)));
}
.annotation {
color: #4444ff;
font-family: monospace;
font-style: italic;
display: none;
-webkit-user-select: none;
}
body:active .annotation {
/* requires holding mouse down anywhere on the page */
display: inline-block;
}
span:hover .annotation {
/* requires hover over a span ONLY on its first line */
display: inline-block;
}
</style>
</head>
<body>
<div class="code" style="counter-reset: line 19"><span class="line"><span><span class="code even" style="--layer: 1"><span class="annotation">@0,1,2,3⦊</span>pub fn used_inline_function() <span class="annotation">⦉@0,1,2,3</span></span></span><span class="code" style="--layer: 0">{</span></span>
<span class="line"><span class="code" style="--layer: 0"> // Initialize test constants in a way that cannot be determined at compile time, to ensure</span></span>
<span class="line"><span class="code" style="--layer: 0"> // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from</span></span>
<span class="line"><span class="code" style="--layer: 0"> // dependent conditions.</span></span>
<span class="line"><span class="code" style="--layer: 0"> let </span><span><span class="code even" style="--layer: 1" title="24:19-24:35: @0.Call: _4 = std::env::args() -&gt; [return: bb1, unwind: bb9]
24:19-24:35: @1[0]: _3 = &amp;_4
24:19-24:41: @1.Call: _2 = &lt;std::env::Args as std::iter::ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb8]
24:19-24:46: @2[1]: _1 = Eq(move _2, const 1_usize)
24:9-24:16: @2[3]: FakeRead(ForLet, _1)
25:25-25:26: @3[2]: _5 = const 0_i32
25:9-25:22: @3[3]: FakeRead(ForLet, _5)
26:8-26:15: @3[6]: _7 = _1"><span class="annotation">@0,1,2,3⦊</span>is_true = std::env::args().len() == 1;</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="24:19-24:35: @0.Call: _4 = std::env::args() -&gt; [return: bb1, unwind: bb9]
24:19-24:35: @1[0]: _3 = &amp;_4
24:19-24:41: @1.Call: _2 = &lt;std::env::Args as std::iter::ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb8]
24:19-24:46: @2[1]: _1 = Eq(move _2, const 1_usize)
24:9-24:16: @2[3]: FakeRead(ForLet, _1)
25:25-25:26: @3[2]: _5 = const 0_i32
25:9-25:22: @3[3]: FakeRead(ForLet, _5)
26:8-26:15: @3[6]: _7 = _1"> let mut countdown = 0;</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="24:19-24:35: @0.Call: _4 = std::env::args() -&gt; [return: bb1, unwind: bb9]
24:19-24:35: @1[0]: _3 = &amp;_4
24:19-24:41: @1.Call: _2 = &lt;std::env::Args as std::iter::ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb8]
24:19-24:46: @2[1]: _1 = Eq(move _2, const 1_usize)
24:9-24:16: @2[3]: FakeRead(ForLet, _1)
25:25-25:26: @3[2]: _5 = const 0_i32
25:9-25:22: @3[3]: FakeRead(ForLet, _5)
26:8-26:15: @3[6]: _7 = _1"> if is_true<span class="annotation">⦉@0,1,2,3</span></span></span><span class="code" style="--layer: 0"> </span><span><span class="code odd" style="--layer: 1" title="27:9-27:23: @4[0]: _5 = const 10_i32
26:16-28:6: @4[1]: _6 = const ()"><span class="annotation">@4⦊</span>{</span></span>
<span class="line"><span class="code odd" style="--layer: 1" title="27:9-27:23: @4[0]: _5 = const 10_i32
26:16-28:6: @4[1]: _6 = const ()"> countdown = 10;</span></span>
<span class="line"><span class="code odd" style="--layer: 1" title="27:9-27:23: @4[0]: _5 = const 10_i32
26:16-28:6: @4[1]: _6 = const ()"> }<span class="annotation">⦉@4</span></span></span><span><span class="code even" style="--layer: 1" title="28:6-28:6: @5[0]: _6 = const ()"><span class="annotation">@5⦊</span><span class="annotation">⦉@5</span></span></span><span class="code" style="--layer: 0"></span></span>
<span class="line"><span class="code" style="--layer: 0"> </span><span><span class="code odd" style="--layer: 1" title="29:5-29:25: @6.Call: _8 = use_this_lib_crate() -&gt; [return: bb7, unwind: bb9]
30:2-30:2: @7.Return: return"><span class="annotation">@6,7⦊</span>use_this_lib_crate();</span></span>
<span class="line"><span class="code odd" style="--layer: 1" title="29:5-29:25: @6.Call: _8 = use_this_lib_crate() -&gt; [return: bb7, unwind: bb9]
30:2-30:2: @7.Return: return">}<span class="annotation">⦉@6,7</span></span></span></span></div>
</body>
</html>

View file

@ -0,0 +1,133 @@
<!DOCTYPE html>
<!--
Preview this file as rendered HTML from the github source at:
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_only_from_bin_crate_generic_function.-------.InstrumentCoverage.0.html
For revisions in Pull Requests (PR):
* Replace "rust-lang" with the github PR author
* Replace "master" with the PR branch name
-->
<html>
<head>
<title>used_inline_crate.used_only_from_bin_crate_generic_function - Coverage Spans</title>
<style>
.line {
counter-increment: line;
}
.line:before {
content: counter(line) ": ";
font-family: Menlo, Monaco, monospace;
font-style: italic;
width: 3.8em;
display: inline-block;
text-align: right;
filter: opacity(50%);
-webkit-user-select: none;
}
.code {
color: #dddddd;
background-color: #222222;
font-family: Menlo, Monaco, monospace;
line-height: 1.4em;
border-bottom: 2px solid #222222;
white-space: pre;
display: inline-block;
}
.odd {
background-color: #55bbff;
color: #223311;
}
.even {
background-color: #ee7756;
color: #551133;
}
.code {
--index: calc(var(--layer) - 1);
padding-top: calc(var(--index) * 0.15em);
filter:
hue-rotate(calc(var(--index) * 25deg))
saturate(calc(100% - (var(--index) * 2%)))
brightness(calc(100% - (var(--index) * 1.5%)));
}
.annotation {
color: #4444ff;
font-family: monospace;
font-style: italic;
display: none;
-webkit-user-select: none;
}
body:active .annotation {
/* requires holding mouse down anywhere on the page */
display: inline-block;
}
span:hover .annotation {
/* requires hover over a span ONLY on its first line */
display: inline-block;
}
</style>
</head>
<body>
<div class="code" style="counter-reset: line 38"><span class="line"><span><span class="code even" style="--layer: 1" title="40:14-40:67: @0[6]: _19 = const used_only_from_bin_crate_generic_function::&lt;T&gt;::promoted[0]
40:14-40:67: @0[7]: _7 = &amp;(*_19)
40:14-40:67: @0[8]: _6 = &amp;(*_7)
40:14-40:67: @0[9]: _5 = move _6 as &amp;[&amp;str] (Pointer(Unsize))
40:69-40:72: @0[17]: _14 = &amp;_1
40:5-40:74: @0[18]: _13 = (move _14,)
40:5-40:74: @0[20]: FakeRead(ForMatchedPlace, _13)
40:5-40:74: @0[22]: _15 = (_13.0: &amp;T)
40:5-40:74: @0[25]: _17 = &amp;(*_15)
40:5-40:74: @0[27]: _18 = &lt;T as std::fmt::Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r T, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
40:5-40:74: @0.Call: _16 = std::fmt::ArgumentV1::new::&lt;T&gt;(move _17, move _18) -&gt; [return: bb1, unwind: bb5]
40:5-40:74: @1[2]: _12 = [move _16]
40:5-40:74: @1[5]: _11 = &amp;_12
40:5-40:74: @1[6]: _10 = &amp;(*_11)
40:5-40:74: @1[7]: _9 = move _10 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
40:5-40:74: @1.Call: _4 = std::fmt::Arguments::new_v1(move _5, move _9) -&gt; [return: bb2, unwind: bb5]
40:5-40:74: @2.Call: _3 = std::io::_print(move _4) -&gt; [return: bb3, unwind: bb5]
40:5-40:74: @3[6]: _2 = const ()
39:68-41:2: @3[8]: _0 = const ()
41:2-41:2: @4.Return: return"><span class="annotation">@0,1,2,3,4⦊</span>pub fn used_only_from_bin_crate_generic_function&lt;T: Debug&gt;(arg: T) {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="40:14-40:67: @0[6]: _19 = const used_only_from_bin_crate_generic_function::&lt;T&gt;::promoted[0]
40:14-40:67: @0[7]: _7 = &amp;(*_19)
40:14-40:67: @0[8]: _6 = &amp;(*_7)
40:14-40:67: @0[9]: _5 = move _6 as &amp;[&amp;str] (Pointer(Unsize))
40:69-40:72: @0[17]: _14 = &amp;_1
40:5-40:74: @0[18]: _13 = (move _14,)
40:5-40:74: @0[20]: FakeRead(ForMatchedPlace, _13)
40:5-40:74: @0[22]: _15 = (_13.0: &amp;T)
40:5-40:74: @0[25]: _17 = &amp;(*_15)
40:5-40:74: @0[27]: _18 = &lt;T as std::fmt::Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r T, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
40:5-40:74: @0.Call: _16 = std::fmt::ArgumentV1::new::&lt;T&gt;(move _17, move _18) -&gt; [return: bb1, unwind: bb5]
40:5-40:74: @1[2]: _12 = [move _16]
40:5-40:74: @1[5]: _11 = &amp;_12
40:5-40:74: @1[6]: _10 = &amp;(*_11)
40:5-40:74: @1[7]: _9 = move _10 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
40:5-40:74: @1.Call: _4 = std::fmt::Arguments::new_v1(move _5, move _9) -&gt; [return: bb2, unwind: bb5]
40:5-40:74: @2.Call: _3 = std::io::_print(move _4) -&gt; [return: bb3, unwind: bb5]
40:5-40:74: @3[6]: _2 = const ()
39:68-41:2: @3[8]: _0 = const ()
41:2-41:2: @4.Return: return"> println!("used_only_from_bin_crate_generic_function with {:?}", arg);</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="40:14-40:67: @0[6]: _19 = const used_only_from_bin_crate_generic_function::&lt;T&gt;::promoted[0]
40:14-40:67: @0[7]: _7 = &amp;(*_19)
40:14-40:67: @0[8]: _6 = &amp;(*_7)
40:14-40:67: @0[9]: _5 = move _6 as &amp;[&amp;str] (Pointer(Unsize))
40:69-40:72: @0[17]: _14 = &amp;_1
40:5-40:74: @0[18]: _13 = (move _14,)
40:5-40:74: @0[20]: FakeRead(ForMatchedPlace, _13)
40:5-40:74: @0[22]: _15 = (_13.0: &amp;T)
40:5-40:74: @0[25]: _17 = &amp;(*_15)
40:5-40:74: @0[27]: _18 = &lt;T as std::fmt::Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r T, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
40:5-40:74: @0.Call: _16 = std::fmt::ArgumentV1::new::&lt;T&gt;(move _17, move _18) -&gt; [return: bb1, unwind: bb5]
40:5-40:74: @1[2]: _12 = [move _16]
40:5-40:74: @1[5]: _11 = &amp;_12
40:5-40:74: @1[6]: _10 = &amp;(*_11)
40:5-40:74: @1[7]: _9 = move _10 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
40:5-40:74: @1.Call: _4 = std::fmt::Arguments::new_v1(move _5, move _9) -&gt; [return: bb2, unwind: bb5]
40:5-40:74: @2.Call: _3 = std::io::_print(move _4) -&gt; [return: bb3, unwind: bb5]
40:5-40:74: @3[6]: _2 = const ()
39:68-41:2: @3[8]: _0 = const ()
41:2-41:2: @4.Return: return">}<span class="annotation">⦉@0,1,2,3,4</span></span></span></span></div>
</body>
</html>

View file

@ -0,0 +1,133 @@
<!DOCTYPE html>
<!--
Preview this file as rendered HTML from the github source at:
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_only_from_this_lib_crate_generic_function.-------.InstrumentCoverage.0.html
For revisions in Pull Requests (PR):
* Replace "rust-lang" with the github PR author
* Replace "master" with the PR branch name
-->
<html>
<head>
<title>used_inline_crate.used_only_from_this_lib_crate_generic_function - Coverage Spans</title>
<style>
.line {
counter-increment: line;
}
.line:before {
content: counter(line) ": ";
font-family: Menlo, Monaco, monospace;
font-style: italic;
width: 3.8em;
display: inline-block;
text-align: right;
filter: opacity(50%);
-webkit-user-select: none;
}
.code {
color: #dddddd;
background-color: #222222;
font-family: Menlo, Monaco, monospace;
line-height: 1.4em;
border-bottom: 2px solid #222222;
white-space: pre;
display: inline-block;
}
.odd {
background-color: #55bbff;
color: #223311;
}
.even {
background-color: #ee7756;
color: #551133;
}
.code {
--index: calc(var(--layer) - 1);
padding-top: calc(var(--index) * 0.15em);
filter:
hue-rotate(calc(var(--index) * 25deg))
saturate(calc(100% - (var(--index) * 2%)))
brightness(calc(100% - (var(--index) * 1.5%)));
}
.annotation {
color: #4444ff;
font-family: monospace;
font-style: italic;
display: none;
-webkit-user-select: none;
}
body:active .annotation {
/* requires holding mouse down anywhere on the page */
display: inline-block;
}
span:hover .annotation {
/* requires hover over a span ONLY on its first line */
display: inline-block;
}
</style>
</head>
<body>
<div class="code" style="counter-reset: line 44"><span class="line"><span><span class="code even" style="--layer: 1" title="46:14-46:72: @0[6]: _19 = const used_only_from_this_lib_crate_generic_function::&lt;T&gt;::promoted[0]
46:14-46:72: @0[7]: _7 = &amp;(*_19)
46:14-46:72: @0[8]: _6 = &amp;(*_7)
46:14-46:72: @0[9]: _5 = move _6 as &amp;[&amp;str] (Pointer(Unsize))
46:74-46:77: @0[17]: _14 = &amp;_1
46:5-46:79: @0[18]: _13 = (move _14,)
46:5-46:79: @0[20]: FakeRead(ForMatchedPlace, _13)
46:5-46:79: @0[22]: _15 = (_13.0: &amp;T)
46:5-46:79: @0[25]: _17 = &amp;(*_15)
46:5-46:79: @0[27]: _18 = &lt;T as std::fmt::Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r T, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
46:5-46:79: @0.Call: _16 = std::fmt::ArgumentV1::new::&lt;T&gt;(move _17, move _18) -&gt; [return: bb1, unwind: bb5]
46:5-46:79: @1[2]: _12 = [move _16]
46:5-46:79: @1[5]: _11 = &amp;_12
46:5-46:79: @1[6]: _10 = &amp;(*_11)
46:5-46:79: @1[7]: _9 = move _10 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
46:5-46:79: @1.Call: _4 = std::fmt::Arguments::new_v1(move _5, move _9) -&gt; [return: bb2, unwind: bb5]
46:5-46:79: @2.Call: _3 = std::io::_print(move _4) -&gt; [return: bb3, unwind: bb5]
46:5-46:79: @3[6]: _2 = const ()
45:73-47:2: @3[8]: _0 = const ()
47:2-47:2: @4.Return: return"><span class="annotation">@0,1,2,3,4⦊</span>pub fn used_only_from_this_lib_crate_generic_function&lt;T: Debug&gt;(arg: T) {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="46:14-46:72: @0[6]: _19 = const used_only_from_this_lib_crate_generic_function::&lt;T&gt;::promoted[0]
46:14-46:72: @0[7]: _7 = &amp;(*_19)
46:14-46:72: @0[8]: _6 = &amp;(*_7)
46:14-46:72: @0[9]: _5 = move _6 as &amp;[&amp;str] (Pointer(Unsize))
46:74-46:77: @0[17]: _14 = &amp;_1
46:5-46:79: @0[18]: _13 = (move _14,)
46:5-46:79: @0[20]: FakeRead(ForMatchedPlace, _13)
46:5-46:79: @0[22]: _15 = (_13.0: &amp;T)
46:5-46:79: @0[25]: _17 = &amp;(*_15)
46:5-46:79: @0[27]: _18 = &lt;T as std::fmt::Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r T, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
46:5-46:79: @0.Call: _16 = std::fmt::ArgumentV1::new::&lt;T&gt;(move _17, move _18) -&gt; [return: bb1, unwind: bb5]
46:5-46:79: @1[2]: _12 = [move _16]
46:5-46:79: @1[5]: _11 = &amp;_12
46:5-46:79: @1[6]: _10 = &amp;(*_11)
46:5-46:79: @1[7]: _9 = move _10 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
46:5-46:79: @1.Call: _4 = std::fmt::Arguments::new_v1(move _5, move _9) -&gt; [return: bb2, unwind: bb5]
46:5-46:79: @2.Call: _3 = std::io::_print(move _4) -&gt; [return: bb3, unwind: bb5]
46:5-46:79: @3[6]: _2 = const ()
45:73-47:2: @3[8]: _0 = const ()
47:2-47:2: @4.Return: return"> println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="46:14-46:72: @0[6]: _19 = const used_only_from_this_lib_crate_generic_function::&lt;T&gt;::promoted[0]
46:14-46:72: @0[7]: _7 = &amp;(*_19)
46:14-46:72: @0[8]: _6 = &amp;(*_7)
46:14-46:72: @0[9]: _5 = move _6 as &amp;[&amp;str] (Pointer(Unsize))
46:74-46:77: @0[17]: _14 = &amp;_1
46:5-46:79: @0[18]: _13 = (move _14,)
46:5-46:79: @0[20]: FakeRead(ForMatchedPlace, _13)
46:5-46:79: @0[22]: _15 = (_13.0: &amp;T)
46:5-46:79: @0[25]: _17 = &amp;(*_15)
46:5-46:79: @0[27]: _18 = &lt;T as std::fmt::Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r T, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
46:5-46:79: @0.Call: _16 = std::fmt::ArgumentV1::new::&lt;T&gt;(move _17, move _18) -&gt; [return: bb1, unwind: bb5]
46:5-46:79: @1[2]: _12 = [move _16]
46:5-46:79: @1[5]: _11 = &amp;_12
46:5-46:79: @1[6]: _10 = &amp;(*_11)
46:5-46:79: @1[7]: _9 = move _10 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
46:5-46:79: @1.Call: _4 = std::fmt::Arguments::new_v1(move _5, move _9) -&gt; [return: bb2, unwind: bb5]
46:5-46:79: @2.Call: _3 = std::io::_print(move _4) -&gt; [return: bb3, unwind: bb5]
46:5-46:79: @3[6]: _2 = const ()
45:73-47:2: @3[8]: _0 = const ()
47:2-47:2: @4.Return: return">}<span class="annotation">⦉@0,1,2,3,4</span></span></span></span></div>
</body>
</html>

View file

@ -0,0 +1,133 @@
<!DOCTYPE html>
<!--
Preview this file as rendered HTML from the github source at:
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_with_same_type_from_bin_crate_and_lib_crate_generic_function.-------.InstrumentCoverage.0.html
For revisions in Pull Requests (PR):
* Replace "rust-lang" with the github PR author
* Replace "master" with the PR branch name
-->
<html>
<head>
<title>used_inline_crate.used_with_same_type_from_bin_crate_and_lib_crate_generic_function - Coverage Spans</title>
<style>
.line {
counter-increment: line;
}
.line:before {
content: counter(line) ": ";
font-family: Menlo, Monaco, monospace;
font-style: italic;
width: 3.8em;
display: inline-block;
text-align: right;
filter: opacity(50%);
-webkit-user-select: none;
}
.code {
color: #dddddd;
background-color: #222222;
font-family: Menlo, Monaco, monospace;
line-height: 1.4em;
border-bottom: 2px solid #222222;
white-space: pre;
display: inline-block;
}
.odd {
background-color: #55bbff;
color: #223311;
}
.even {
background-color: #ee7756;
color: #551133;
}
.code {
--index: calc(var(--layer) - 1);
padding-top: calc(var(--index) * 0.15em);
filter:
hue-rotate(calc(var(--index) * 25deg))
saturate(calc(100% - (var(--index) * 2%)))
brightness(calc(100% - (var(--index) * 1.5%)));
}
.annotation {
color: #4444ff;
font-family: monospace;
font-style: italic;
display: none;
-webkit-user-select: none;
}
body:active .annotation {
/* requires holding mouse down anywhere on the page */
display: inline-block;
}
span:hover .annotation {
/* requires hover over a span ONLY on its first line */
display: inline-block;
}
</style>
</head>
<body>
<div class="code" style="counter-reset: line 54"><span class="line"><span><span class="code even" style="--layer: 1" title="56:14-56:91: @0[6]: _19 = const used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;T&gt;::promoted[0]
56:14-56:91: @0[7]: _7 = &amp;(*_19)
56:14-56:91: @0[8]: _6 = &amp;(*_7)
56:14-56:91: @0[9]: _5 = move _6 as &amp;[&amp;str] (Pointer(Unsize))
56:93-56:96: @0[17]: _14 = &amp;_1
56:5-56:98: @0[18]: _13 = (move _14,)
56:5-56:98: @0[20]: FakeRead(ForMatchedPlace, _13)
56:5-56:98: @0[22]: _15 = (_13.0: &amp;T)
56:5-56:98: @0[25]: _17 = &amp;(*_15)
56:5-56:98: @0[27]: _18 = &lt;T as std::fmt::Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r T, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
56:5-56:98: @0.Call: _16 = std::fmt::ArgumentV1::new::&lt;T&gt;(move _17, move _18) -&gt; [return: bb1, unwind: bb5]
56:5-56:98: @1[2]: _12 = [move _16]
56:5-56:98: @1[5]: _11 = &amp;_12
56:5-56:98: @1[6]: _10 = &amp;(*_11)
56:5-56:98: @1[7]: _9 = move _10 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
56:5-56:98: @1.Call: _4 = std::fmt::Arguments::new_v1(move _5, move _9) -&gt; [return: bb2, unwind: bb5]
56:5-56:98: @2.Call: _3 = std::io::_print(move _4) -&gt; [return: bb3, unwind: bb5]
56:5-56:98: @3[6]: _2 = const ()
55:92-57:2: @3[8]: _0 = const ()
57:2-57:2: @4.Return: return"><span class="annotation">@0,1,2,3,4⦊</span>pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function&lt;T: Debug&gt;(arg: T) {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="56:14-56:91: @0[6]: _19 = const used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;T&gt;::promoted[0]
56:14-56:91: @0[7]: _7 = &amp;(*_19)
56:14-56:91: @0[8]: _6 = &amp;(*_7)
56:14-56:91: @0[9]: _5 = move _6 as &amp;[&amp;str] (Pointer(Unsize))
56:93-56:96: @0[17]: _14 = &amp;_1
56:5-56:98: @0[18]: _13 = (move _14,)
56:5-56:98: @0[20]: FakeRead(ForMatchedPlace, _13)
56:5-56:98: @0[22]: _15 = (_13.0: &amp;T)
56:5-56:98: @0[25]: _17 = &amp;(*_15)
56:5-56:98: @0[27]: _18 = &lt;T as std::fmt::Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r T, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
56:5-56:98: @0.Call: _16 = std::fmt::ArgumentV1::new::&lt;T&gt;(move _17, move _18) -&gt; [return: bb1, unwind: bb5]
56:5-56:98: @1[2]: _12 = [move _16]
56:5-56:98: @1[5]: _11 = &amp;_12
56:5-56:98: @1[6]: _10 = &amp;(*_11)
56:5-56:98: @1[7]: _9 = move _10 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
56:5-56:98: @1.Call: _4 = std::fmt::Arguments::new_v1(move _5, move _9) -&gt; [return: bb2, unwind: bb5]
56:5-56:98: @2.Call: _3 = std::io::_print(move _4) -&gt; [return: bb3, unwind: bb5]
56:5-56:98: @3[6]: _2 = const ()
55:92-57:2: @3[8]: _0 = const ()
57:2-57:2: @4.Return: return"> println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="56:14-56:91: @0[6]: _19 = const used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;T&gt;::promoted[0]
56:14-56:91: @0[7]: _7 = &amp;(*_19)
56:14-56:91: @0[8]: _6 = &amp;(*_7)
56:14-56:91: @0[9]: _5 = move _6 as &amp;[&amp;str] (Pointer(Unsize))
56:93-56:96: @0[17]: _14 = &amp;_1
56:5-56:98: @0[18]: _13 = (move _14,)
56:5-56:98: @0[20]: FakeRead(ForMatchedPlace, _13)
56:5-56:98: @0[22]: _15 = (_13.0: &amp;T)
56:5-56:98: @0[25]: _17 = &amp;(*_15)
56:5-56:98: @0[27]: _18 = &lt;T as std::fmt::Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r T, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
56:5-56:98: @0.Call: _16 = std::fmt::ArgumentV1::new::&lt;T&gt;(move _17, move _18) -&gt; [return: bb1, unwind: bb5]
56:5-56:98: @1[2]: _12 = [move _16]
56:5-56:98: @1[5]: _11 = &amp;_12
56:5-56:98: @1[6]: _10 = &amp;(*_11)
56:5-56:98: @1[7]: _9 = move _10 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
56:5-56:98: @1.Call: _4 = std::fmt::Arguments::new_v1(move _5, move _9) -&gt; [return: bb2, unwind: bb5]
56:5-56:98: @2.Call: _3 = std::io::_print(move _4) -&gt; [return: bb3, unwind: bb5]
56:5-56:98: @3[6]: _2 = const ()
55:92-57:2: @3[8]: _0 = const ()
57:2-57:2: @4.Return: return">}<span class="annotation">⦉@0,1,2,3,4</span></span></span></span></div>
</body>
</html>

View file

@ -0,0 +1,249 @@
<!DOCTYPE html>
<!--
Preview this file as rendered HTML from the github source at:
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_inline_crate/uses_inline_crate.main.-------.InstrumentCoverage.0.html
For revisions in Pull Requests (PR):
* Replace "rust-lang" with the github PR author
* Replace "master" with the PR branch name
-->
<html>
<head>
<title>uses_inline_crate.main - Coverage Spans</title>
<style>
.line {
counter-increment: line;
}
.line:before {
content: counter(line) ": ";
font-family: Menlo, Monaco, monospace;
font-style: italic;
width: 3.8em;
display: inline-block;
text-align: right;
filter: opacity(50%);
-webkit-user-select: none;
}
.code {
color: #dddddd;
background-color: #222222;
font-family: Menlo, Monaco, monospace;
line-height: 1.4em;
border-bottom: 2px solid #222222;
white-space: pre;
display: inline-block;
}
.odd {
background-color: #55bbff;
color: #223311;
}
.even {
background-color: #ee7756;
color: #551133;
}
.code {
--index: calc(var(--layer) - 1);
padding-top: calc(var(--index) * 0.15em);
filter:
hue-rotate(calc(var(--index) * 25deg))
saturate(calc(100% - (var(--index) * 2%)))
brightness(calc(100% - (var(--index) * 1.5%)));
}
.annotation {
color: #4444ff;
font-family: monospace;
font-style: italic;
display: none;
-webkit-user-select: none;
}
body:active .annotation {
/* requires holding mouse down anywhere on the page */
display: inline-block;
}
span:hover .annotation {
/* requires hover over a span ONLY on its first line */
display: inline-block;
}
</style>
</head>
<body>
<div class="code" style="counter-reset: line 6"><span class="line"><span><span class="code even" style="--layer: 1" title="8:5-8:39: @0.Call: _1 = used_inline_crate::used_function() -&gt; [return: bb1, unwind: bb15]
9:5-9:46: @1.Call: _2 = used_inline_crate::used_inline_function() -&gt; [return: bb2, unwind: bb15]
10:20-10:36: @2[5]: _6 = Box([i32; 4])
10:20-10:36: @2[6]: (*_6) = [const 1_i32, const 2_i32, const 3_i32, const 4_i32]
10:20-10:36: @2[7]: _5 = move _6
10:20-10:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
10:20-10:36: @4.Call: _3 = std::slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb14]
10:9-10:17: @5[1]: FakeRead(ForLet, _3)
11:66-11:75: @5[4]: _8 = &amp;_3
11:5-11:76: @5.Call: _7 = used_inline_crate::used_only_from_bin_crate_generic_function::&lt;&amp;std::vec::Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb12]
12:5-12:96: @6.Call: _9 = used_inline_crate::used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb7, unwind: bb12]
13:75-13:83: @7[3]: _11 = move _3
13:5-13:84: @7.Call: _10 = used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::&lt;std::vec::Vec&lt;i32&gt;&gt;(move _11) -&gt; [return: bb8, unwind: bb11]
14:5-16:6: @8.Call: _12 = used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb9, unwind: bb12]
7:11-17:2: @9[1]: _0 = const ()
17:2-17:2: @10.Return: return"><span class="annotation">@0,1,2,3,4,5,6,7,8,9,10⦊</span>fn main() {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="8:5-8:39: @0.Call: _1 = used_inline_crate::used_function() -&gt; [return: bb1, unwind: bb15]
9:5-9:46: @1.Call: _2 = used_inline_crate::used_inline_function() -&gt; [return: bb2, unwind: bb15]
10:20-10:36: @2[5]: _6 = Box([i32; 4])
10:20-10:36: @2[6]: (*_6) = [const 1_i32, const 2_i32, const 3_i32, const 4_i32]
10:20-10:36: @2[7]: _5 = move _6
10:20-10:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
10:20-10:36: @4.Call: _3 = std::slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb14]
10:9-10:17: @5[1]: FakeRead(ForLet, _3)
11:66-11:75: @5[4]: _8 = &amp;_3
11:5-11:76: @5.Call: _7 = used_inline_crate::used_only_from_bin_crate_generic_function::&lt;&amp;std::vec::Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb12]
12:5-12:96: @6.Call: _9 = used_inline_crate::used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb7, unwind: bb12]
13:75-13:83: @7[3]: _11 = move _3
13:5-13:84: @7.Call: _10 = used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::&lt;std::vec::Vec&lt;i32&gt;&gt;(move _11) -&gt; [return: bb8, unwind: bb11]
14:5-16:6: @8.Call: _12 = used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb9, unwind: bb12]
7:11-17:2: @9[1]: _0 = const ()
17:2-17:2: @10.Return: return"> used_inline_crate::used_function();</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="8:5-8:39: @0.Call: _1 = used_inline_crate::used_function() -&gt; [return: bb1, unwind: bb15]
9:5-9:46: @1.Call: _2 = used_inline_crate::used_inline_function() -&gt; [return: bb2, unwind: bb15]
10:20-10:36: @2[5]: _6 = Box([i32; 4])
10:20-10:36: @2[6]: (*_6) = [const 1_i32, const 2_i32, const 3_i32, const 4_i32]
10:20-10:36: @2[7]: _5 = move _6
10:20-10:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
10:20-10:36: @4.Call: _3 = std::slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb14]
10:9-10:17: @5[1]: FakeRead(ForLet, _3)
11:66-11:75: @5[4]: _8 = &amp;_3
11:5-11:76: @5.Call: _7 = used_inline_crate::used_only_from_bin_crate_generic_function::&lt;&amp;std::vec::Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb12]
12:5-12:96: @6.Call: _9 = used_inline_crate::used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb7, unwind: bb12]
13:75-13:83: @7[3]: _11 = move _3
13:5-13:84: @7.Call: _10 = used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::&lt;std::vec::Vec&lt;i32&gt;&gt;(move _11) -&gt; [return: bb8, unwind: bb11]
14:5-16:6: @8.Call: _12 = used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb9, unwind: bb12]
7:11-17:2: @9[1]: _0 = const ()
17:2-17:2: @10.Return: return"> used_inline_crate::used_inline_function();</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="8:5-8:39: @0.Call: _1 = used_inline_crate::used_function() -&gt; [return: bb1, unwind: bb15]
9:5-9:46: @1.Call: _2 = used_inline_crate::used_inline_function() -&gt; [return: bb2, unwind: bb15]
10:20-10:36: @2[5]: _6 = Box([i32; 4])
10:20-10:36: @2[6]: (*_6) = [const 1_i32, const 2_i32, const 3_i32, const 4_i32]
10:20-10:36: @2[7]: _5 = move _6
10:20-10:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
10:20-10:36: @4.Call: _3 = std::slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb14]
10:9-10:17: @5[1]: FakeRead(ForLet, _3)
11:66-11:75: @5[4]: _8 = &amp;_3
11:5-11:76: @5.Call: _7 = used_inline_crate::used_only_from_bin_crate_generic_function::&lt;&amp;std::vec::Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb12]
12:5-12:96: @6.Call: _9 = used_inline_crate::used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb7, unwind: bb12]
13:75-13:83: @7[3]: _11 = move _3
13:5-13:84: @7.Call: _10 = used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::&lt;std::vec::Vec&lt;i32&gt;&gt;(move _11) -&gt; [return: bb8, unwind: bb11]
14:5-16:6: @8.Call: _12 = used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb9, unwind: bb12]
7:11-17:2: @9[1]: _0 = const ()
17:2-17:2: @10.Return: return"> let some_vec = vec![1, 2, 3, 4];</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="8:5-8:39: @0.Call: _1 = used_inline_crate::used_function() -&gt; [return: bb1, unwind: bb15]
9:5-9:46: @1.Call: _2 = used_inline_crate::used_inline_function() -&gt; [return: bb2, unwind: bb15]
10:20-10:36: @2[5]: _6 = Box([i32; 4])
10:20-10:36: @2[6]: (*_6) = [const 1_i32, const 2_i32, const 3_i32, const 4_i32]
10:20-10:36: @2[7]: _5 = move _6
10:20-10:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
10:20-10:36: @4.Call: _3 = std::slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb14]
10:9-10:17: @5[1]: FakeRead(ForLet, _3)
11:66-11:75: @5[4]: _8 = &amp;_3
11:5-11:76: @5.Call: _7 = used_inline_crate::used_only_from_bin_crate_generic_function::&lt;&amp;std::vec::Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb12]
12:5-12:96: @6.Call: _9 = used_inline_crate::used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb7, unwind: bb12]
13:75-13:83: @7[3]: _11 = move _3
13:5-13:84: @7.Call: _10 = used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::&lt;std::vec::Vec&lt;i32&gt;&gt;(move _11) -&gt; [return: bb8, unwind: bb11]
14:5-16:6: @8.Call: _12 = used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb9, unwind: bb12]
7:11-17:2: @9[1]: _0 = const ()
17:2-17:2: @10.Return: return"> used_inline_crate::used_only_from_bin_crate_generic_function(&amp;some_vec);</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="8:5-8:39: @0.Call: _1 = used_inline_crate::used_function() -&gt; [return: bb1, unwind: bb15]
9:5-9:46: @1.Call: _2 = used_inline_crate::used_inline_function() -&gt; [return: bb2, unwind: bb15]
10:20-10:36: @2[5]: _6 = Box([i32; 4])
10:20-10:36: @2[6]: (*_6) = [const 1_i32, const 2_i32, const 3_i32, const 4_i32]
10:20-10:36: @2[7]: _5 = move _6
10:20-10:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
10:20-10:36: @4.Call: _3 = std::slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb14]
10:9-10:17: @5[1]: FakeRead(ForLet, _3)
11:66-11:75: @5[4]: _8 = &amp;_3
11:5-11:76: @5.Call: _7 = used_inline_crate::used_only_from_bin_crate_generic_function::&lt;&amp;std::vec::Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb12]
12:5-12:96: @6.Call: _9 = used_inline_crate::used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb7, unwind: bb12]
13:75-13:83: @7[3]: _11 = move _3
13:5-13:84: @7.Call: _10 = used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::&lt;std::vec::Vec&lt;i32&gt;&gt;(move _11) -&gt; [return: bb8, unwind: bb11]
14:5-16:6: @8.Call: _12 = used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb9, unwind: bb12]
7:11-17:2: @9[1]: _0 = const ()
17:2-17:2: @10.Return: return"> used_inline_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="8:5-8:39: @0.Call: _1 = used_inline_crate::used_function() -&gt; [return: bb1, unwind: bb15]
9:5-9:46: @1.Call: _2 = used_inline_crate::used_inline_function() -&gt; [return: bb2, unwind: bb15]
10:20-10:36: @2[5]: _6 = Box([i32; 4])
10:20-10:36: @2[6]: (*_6) = [const 1_i32, const 2_i32, const 3_i32, const 4_i32]
10:20-10:36: @2[7]: _5 = move _6
10:20-10:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
10:20-10:36: @4.Call: _3 = std::slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb14]
10:9-10:17: @5[1]: FakeRead(ForLet, _3)
11:66-11:75: @5[4]: _8 = &amp;_3
11:5-11:76: @5.Call: _7 = used_inline_crate::used_only_from_bin_crate_generic_function::&lt;&amp;std::vec::Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb12]
12:5-12:96: @6.Call: _9 = used_inline_crate::used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb7, unwind: bb12]
13:75-13:83: @7[3]: _11 = move _3
13:5-13:84: @7.Call: _10 = used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::&lt;std::vec::Vec&lt;i32&gt;&gt;(move _11) -&gt; [return: bb8, unwind: bb11]
14:5-16:6: @8.Call: _12 = used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb9, unwind: bb12]
7:11-17:2: @9[1]: _0 = const ()
17:2-17:2: @10.Return: return"> used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="8:5-8:39: @0.Call: _1 = used_inline_crate::used_function() -&gt; [return: bb1, unwind: bb15]
9:5-9:46: @1.Call: _2 = used_inline_crate::used_inline_function() -&gt; [return: bb2, unwind: bb15]
10:20-10:36: @2[5]: _6 = Box([i32; 4])
10:20-10:36: @2[6]: (*_6) = [const 1_i32, const 2_i32, const 3_i32, const 4_i32]
10:20-10:36: @2[7]: _5 = move _6
10:20-10:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
10:20-10:36: @4.Call: _3 = std::slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb14]
10:9-10:17: @5[1]: FakeRead(ForLet, _3)
11:66-11:75: @5[4]: _8 = &amp;_3
11:5-11:76: @5.Call: _7 = used_inline_crate::used_only_from_bin_crate_generic_function::&lt;&amp;std::vec::Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb12]
12:5-12:96: @6.Call: _9 = used_inline_crate::used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb7, unwind: bb12]
13:75-13:83: @7[3]: _11 = move _3
13:5-13:84: @7.Call: _10 = used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::&lt;std::vec::Vec&lt;i32&gt;&gt;(move _11) -&gt; [return: bb8, unwind: bb11]
14:5-16:6: @8.Call: _12 = used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb9, unwind: bb12]
7:11-17:2: @9[1]: _0 = const ()
17:2-17:2: @10.Return: return"> used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function(</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="8:5-8:39: @0.Call: _1 = used_inline_crate::used_function() -&gt; [return: bb1, unwind: bb15]
9:5-9:46: @1.Call: _2 = used_inline_crate::used_inline_function() -&gt; [return: bb2, unwind: bb15]
10:20-10:36: @2[5]: _6 = Box([i32; 4])
10:20-10:36: @2[6]: (*_6) = [const 1_i32, const 2_i32, const 3_i32, const 4_i32]
10:20-10:36: @2[7]: _5 = move _6
10:20-10:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
10:20-10:36: @4.Call: _3 = std::slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb14]
10:9-10:17: @5[1]: FakeRead(ForLet, _3)
11:66-11:75: @5[4]: _8 = &amp;_3
11:5-11:76: @5.Call: _7 = used_inline_crate::used_only_from_bin_crate_generic_function::&lt;&amp;std::vec::Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb12]
12:5-12:96: @6.Call: _9 = used_inline_crate::used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb7, unwind: bb12]
13:75-13:83: @7[3]: _11 = move _3
13:5-13:84: @7.Call: _10 = used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::&lt;std::vec::Vec&lt;i32&gt;&gt;(move _11) -&gt; [return: bb8, unwind: bb11]
14:5-16:6: @8.Call: _12 = used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb9, unwind: bb12]
7:11-17:2: @9[1]: _0 = const ()
17:2-17:2: @10.Return: return"> "interesting?",</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="8:5-8:39: @0.Call: _1 = used_inline_crate::used_function() -&gt; [return: bb1, unwind: bb15]
9:5-9:46: @1.Call: _2 = used_inline_crate::used_inline_function() -&gt; [return: bb2, unwind: bb15]
10:20-10:36: @2[5]: _6 = Box([i32; 4])
10:20-10:36: @2[6]: (*_6) = [const 1_i32, const 2_i32, const 3_i32, const 4_i32]
10:20-10:36: @2[7]: _5 = move _6
10:20-10:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
10:20-10:36: @4.Call: _3 = std::slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb14]
10:9-10:17: @5[1]: FakeRead(ForLet, _3)
11:66-11:75: @5[4]: _8 = &amp;_3
11:5-11:76: @5.Call: _7 = used_inline_crate::used_only_from_bin_crate_generic_function::&lt;&amp;std::vec::Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb12]
12:5-12:96: @6.Call: _9 = used_inline_crate::used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb7, unwind: bb12]
13:75-13:83: @7[3]: _11 = move _3
13:5-13:84: @7.Call: _10 = used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::&lt;std::vec::Vec&lt;i32&gt;&gt;(move _11) -&gt; [return: bb8, unwind: bb11]
14:5-16:6: @8.Call: _12 = used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb9, unwind: bb12]
7:11-17:2: @9[1]: _0 = const ()
17:2-17:2: @10.Return: return"> );</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="8:5-8:39: @0.Call: _1 = used_inline_crate::used_function() -&gt; [return: bb1, unwind: bb15]
9:5-9:46: @1.Call: _2 = used_inline_crate::used_inline_function() -&gt; [return: bb2, unwind: bb15]
10:20-10:36: @2[5]: _6 = Box([i32; 4])
10:20-10:36: @2[6]: (*_6) = [const 1_i32, const 2_i32, const 3_i32, const 4_i32]
10:20-10:36: @2[7]: _5 = move _6
10:20-10:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
10:20-10:36: @4.Call: _3 = std::slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb14]
10:9-10:17: @5[1]: FakeRead(ForLet, _3)
11:66-11:75: @5[4]: _8 = &amp;_3
11:5-11:76: @5.Call: _7 = used_inline_crate::used_only_from_bin_crate_generic_function::&lt;&amp;std::vec::Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb12]
12:5-12:96: @6.Call: _9 = used_inline_crate::used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb7, unwind: bb12]
13:75-13:83: @7[3]: _11 = move _3
13:5-13:84: @7.Call: _10 = used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::&lt;std::vec::Vec&lt;i32&gt;&gt;(move _11) -&gt; [return: bb8, unwind: bb11]
14:5-16:6: @8.Call: _12 = used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb9, unwind: bb12]
7:11-17:2: @9[1]: _0 = const ()
17:2-17:2: @10.Return: return">}<span class="annotation">⦉@0,1,2,3,4,5,6,7,8,9,10</span></span></span></span></div>
</body>
</html>

View file

@ -1,6 +1,6 @@
#![allow(unused_assignments, dead_code)]
// compile-flags: --edition=2018
// compile-flags: --edition=2018 -C opt-level=1 # fix in rustc_mir/monomorphize/partitioning/mod.rs
async fn c(x: u8) -> u8 {
if x == 8 {
@ -10,7 +10,7 @@ async fn c(x: u8) -> u8 {
}
}
async fn d() -> u8 { 1 }
async fn d() -> u8 { 1 } // should have a coverage count `0` (see below)
async fn e() -> u8 { 1 } // unused function; executor does not block on `g()`
@ -126,3 +126,14 @@ pub fn block_on<F: Future>(mut future: F) -> F::Output {
}
}
}
// `llvm-cov show` shows no coverage results for the `d()`, even though the
// crate's LLVM IR shows the function exists and has an InstrProf PGO counter,
// and appears to be registered like all other counted functions.
//
// `llvm-cov show --debug` output shows there is at least one `Counter` for this
// line, but counters do not appear in the `Combined regions` section (unlike
// `f()`, which is similar, but does appear in `Combined regions`, and does show
// coverage). The only difference is, `f()` is awaited, but the call to await
// `d()` is not reached. (Note: `d()` will appear in coverage if the test is
// modified to cause it to be awaited.)

View file

@ -1,5 +1,5 @@
#![allow(unused_assignments, unused_variables)]
// compile-flags: -C opt-level=2 # fix described in rustc_middle/mir/mono.rs
fn main() {
// Initialize test constants in a way that cannot be determined at compile time, to ensure
// rustc and LLVM cannot optimize out statements (or coverage counters) downstream from

View file

@ -1,5 +1,5 @@
#![allow(unused_assignments, unused_variables)]
// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
use std::fmt::Debug;
pub fn used_function() {
@ -17,7 +17,7 @@ pub fn used_function() {
pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
println!("used_only_from_bin_crate_generic_function with {:?}", arg);
}
// Expect for above function: `Unexecuted instantiation` (see below)
pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
}
@ -60,45 +60,41 @@ fn use_this_lib_crate() {
used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
}
// FIXME(#79651): `used_from_bin_crate_and_lib_crate_generic_function()` is covered and executed
// `2` times, but the coverage output also shows (at the bottom of the coverage report):
// ------------------
// | Unexecuted instantiation: <some function name here>
// ------------------
// FIXME(#79651): "Unexecuted instantiation" errors appear in coverage results,
// for example:
//
// Note, the function name shown in the error seems to change depending on the structure of the
// code, for some reason, including:
// | Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_>
//
// * used_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>
// * used_crate::use_this_lib_crate
// These notices appear when `llvm-cov` shows instantiations. This may be a
// default option, but it can be suppressed with:
//
// The `Unexecuted instantiation` error may be related to more than one generic function. Since the
// reporting is not consistent, it may not be obvious if there are multiple problems here; however,
// `used_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>` (which I have seen
// with this error) is the only generic function missing instantiaion coverage counts.
// ```shell
// $ `llvm-cov show --show-instantiations=0 ...`
// ```
//
// The `&str` variant was called from within this `lib` crate, and the `bin` crate also calls this
// function, but with `T` type `&Vec<i32>`.
// The notice is triggered because the function is unused by the library itself,
// and when the library is compiled, a synthetic function is generated, so
// unused function coverage can be reported. Coverage can be skipped for unused
// generic functions with:
//
// I believe the reason is that one or both crates are generating `Zero` counters for what it
// believes are "Unreachable" instantiations, but those instantiations are counted from the
// coverage map in the other crate.
// ```shell
// $ `rustc -Z instrument-coverage=except-unused-generics ...`
// ```
//
// See `add_unreachable_coverage()` in `mapgen.rs` for more on how these `Zero` counters are added
// for what the funciton believes are `DefId`s that did not get codegenned. I suspect the issue
// may be related to this process, but this needs to be confirmed. It may not be possible to know
// for sure if a function is truly unused and should be reported with `Zero` coverage if it may
// still get used from an external crate. (Something to look at: If the `DefId` in MIR corresponds
// _only_ to the generic function without type parameters, is the `DefId` in the codegenned set,
// instantiated with one of the type parameters (in either or both crates) a *different* `DefId`?
// If so, `add_unreachable_coverage()` would assume the MIR `DefId` was uncovered, and would add
// unreachable coverage.
// Even though this function is used by `uses_crate.rs` (and
// counted), with substitutions for `T`, those instantiations are only generated
// when the generic function is actually used (from the binary, not from this
// library crate). So the test result shows coverage for all instantiated
// versions and their generic type substitutions, plus the `Unexecuted
// instantiation` message for the non-substituted version. This is valid, but
// unfortunately a little confusing.
//
// I didn't think they could be different, but if they can, we would need to find the `DefId` for
// the generic function MIR and include it in the set of "codegenned" DefIds if any instantiation
// of that generic function does exist.
// The library crate has its own coverage map, and the only way to show unused
// coverage of a generic function is to include the generic function in the
// coverage map, marked as an "unused function". If the library were used by
// another binary that never used this generic function, then it would be valid
// to show the unused generic, with unknown substitution (`_`).
//
// Note, however, for `used_with_same_type_from_bin_crate_and_lib_crate_generic_function()` both
// crates use this function with the same type variant. The function does not have multiple
// instantiations, so the coverage analysis is not confused. No "Unexecuted instantiations" errors
// are reported.
// The alternative is to exclude all generics from being included in the "unused
// functions" list, which would then omit coverage results for
// `unused_generic_function<T>()`, below.

View file

@ -0,0 +1,90 @@
#![allow(unused_assignments, unused_variables)]
// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
use std::fmt::Debug;
pub fn used_function() {
// Initialize test constants in a way that cannot be determined at compile time, to ensure
// rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
// dependent conditions.
let is_true = std::env::args().len() == 1;
let mut countdown = 0;
if is_true {
countdown = 10;
}
use_this_lib_crate();
}
#[inline(always)]
pub fn used_inline_function() {
// Initialize test constants in a way that cannot be determined at compile time, to ensure
// rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
// dependent conditions.
let is_true = std::env::args().len() == 1;
let mut countdown = 0;
if is_true {
countdown = 10;
}
use_this_lib_crate();
}
// Expect for above function:
//
// | Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_>
//
// With `#[inline(always)]` this function is instantiated twice, in both the library crate (which
// does not use it) and the `uses_inline_crate` binary (which does use/call it).
#[inline(always)]
pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
println!("used_only_from_bin_crate_generic_function with {:?}", arg);
}
// Expect for above function: `Unexecuted instantiation` (see notes in `used_crate.rs`)
#[inline(always)]
pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
}
#[inline(always)]
pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
}
#[inline(always)]
pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
}
#[inline(always)]
pub fn unused_generic_function<T: Debug>(arg: T) {
println!("unused_generic_function with {:?}", arg);
}
#[inline(always)]
pub fn unused_function() {
let is_true = std::env::args().len() == 1;
let mut countdown = 2;
if !is_true {
countdown = 20;
}
}
#[inline(always)]
fn unused_private_function() {
let is_true = std::env::args().len() == 1;
let mut countdown = 2;
if !is_true {
countdown = 20;
}
}
fn use_this_lib_crate() {
used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
"used from library used_crate.rs",
);
let some_vec = vec![5, 6, 7, 8];
used_only_from_this_lib_crate_generic_function(some_vec);
used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
}

View file

@ -0,0 +1,39 @@
fn foo<T>(x: T) {
let mut i = 0;
while i < 10 {
i != 0 || i != 0;
i += 1;
}
}
fn unused_template_func<T>(x: T) {
let mut i = 0;
while i < 10 {
i != 0 || i != 0;
i += 1;
}
}
fn unused_func(mut a: u32) {
if a != 0 {
a += 1;
}
}
fn unused_func2(mut a: u32) {
if a != 0 {
a += 1;
}
}
fn unused_func3(mut a: u32) {
if a != 0 {
a += 1;
}
}
fn main() -> Result<(), u8> {
foo::<u32>(0);
foo::<f32>(0.0);
Ok(())
}

View file

@ -1,5 +1,5 @@
#![allow(unused_assignments, unused_variables)]
// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
extern crate used_crate;
fn main() {

View file

@ -0,0 +1,17 @@
#![allow(unused_assignments, unused_variables)]
// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
extern crate used_inline_crate;
fn main() {
used_inline_crate::used_function();
used_inline_crate::used_inline_function();
let some_vec = vec![1, 2, 3, 4];
used_inline_crate::used_only_from_bin_crate_generic_function(&some_vec);
used_inline_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");
used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);
used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
"interesting?",
);
}