1| |#![allow(unused_assignments, unused_variables)] 2| | 3| |use std::fmt::Debug; 4| | 5| 1|pub fn used_function() { 6| | // Initialize test constants in a way that cannot be determined at compile time, to ensure 7| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from 8| | // dependent conditions. 9| 1| let is_true = std::env::args().len() == 1; 10| 1| let mut countdown = 0; 11| 1| if is_true { 12| 1| countdown = 10; 13| 1| } ^0 14| 1| use_this_lib_crate(); 15| 1|} 16| | 17| 2|pub fn used_only_from_bin_crate_generic_function(arg: T) { 18| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg); 19| 2|} ------------------ | used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec>: | 17| 1|pub fn used_only_from_bin_crate_generic_function(arg: T) { | 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg); | 19| 1|} ------------------ | used_crate::used_only_from_bin_crate_generic_function::<&str>: | 17| 1|pub fn used_only_from_bin_crate_generic_function(arg: T) { | 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg); | 19| 1|} ------------------ 20| | 21| 2|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { 22| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); 23| 2|} ------------------ | used_crate::used_only_from_this_lib_crate_generic_function::>: | 21| 1|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { | 22| 1| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); | 23| 1|} ------------------ | used_crate::used_only_from_this_lib_crate_generic_function::<&str>: | 21| 1|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { | 22| 1| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); | 23| 1|} ------------------ 24| | 25| 2|pub fn used_from_bin_crate_and_lib_crate_generic_function(arg: T) { 26| 2| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); 27| 2|} ------------------ | used_crate::used_from_bin_crate_and_lib_crate_generic_function::>: | 25| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function(arg: T) { | 26| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); | 27| 1|} ------------------ | used_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>: | 25| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function(arg: T) { | 26| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); | 27| 1|} ------------------ 28| | 29| 2|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function(arg: T) { 30| 2| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); 31| 2|} 32| | 33| 0|pub fn unused_generic_function(arg: T) { 34| 0| println!("unused_generic_function with {:?}", arg); 35| 0|} 36| | 37| 0|pub fn unused_function() { 38| 0| let is_true = std::env::args().len() == 1; 39| 0| let mut countdown = 2; 40| 0| if !is_true { 41| 0| countdown = 20; 42| 0| } 43| 0|} 44| | 45| 0|fn unused_private_function() { 46| 0| let is_true = std::env::args().len() == 1; 47| 0| let mut countdown = 2; 48| 0| if !is_true { 49| 0| countdown = 20; 50| 0| } 51| 0|} 52| | 53| 1|fn use_this_lib_crate() { 54| 1| used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs"); 55| 1| used_with_same_type_from_bin_crate_and_lib_crate_generic_function( 56| 1| "used from library used_crate.rs", 57| 1| ); 58| 1| let some_vec = vec![5, 6, 7, 8]; 59| 1| used_only_from_this_lib_crate_generic_function(some_vec); 60| 1| used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs"); 61| 1|} ------------------ | Unexecuted instantiation: used_crate::use_this_lib_crate ------------------ 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: 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 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. 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`. 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.