|
12 | 12 | 12| 1| countdown = 10;
|
13 | 13 | 13| 1| }
|
14 | 14 | ^0
|
15 |
| - 14| 1| used_twice_generic_function("some str"); |
| 15 | + 14| 1| use_this_lib_crate(); |
16 | 16 | 15| 1|}
|
17 | 17 | 16| |
|
18 |
| - 17| 1|pub fn used_generic_function<T: Debug>(arg: T) { |
19 |
| - 18| 1| println!("used_generic_function with {:?}", arg); |
20 |
| - 19| 1|} |
| 18 | + 17| 2|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) { |
| 19 | + 18| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg); |
| 20 | + 19| 2|} |
| 21 | + ------------------ |
| 22 | + | used_crate::used_only_from_bin_crate_generic_function::<&str>: |
| 23 | + | 17| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) { |
| 24 | + | 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg); |
| 25 | + | 19| 1|} |
| 26 | + ------------------ |
| 27 | + | used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>: |
| 28 | + | 17| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) { |
| 29 | + | 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg); |
| 30 | + | 19| 1|} |
| 31 | + ------------------ |
21 | 32 | 20| |
|
22 |
| - 21| 2|pub fn used_twice_generic_function<T: Debug>(arg: T) { |
23 |
| - 22| 2| println!("used_twice_generic_function with {:?}", arg); |
| 33 | + 21| 2|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) { |
| 34 | + 22| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); |
24 | 35 | 23| 2|}
|
25 | 36 | ------------------
|
26 |
| - | uses_crate::used_crate::used_twice_generic_function::<alloc::vec::Vec<i32>>: |
27 |
| - | 21| 1|pub fn used_twice_generic_function<T: Debug>(arg: T) { |
28 |
| - | 22| 1| println!("used_twice_generic_function with {:?}", arg); |
| 37 | + | used_crate::used_only_from_this_lib_crate_generic_function::<alloc::vec::Vec<i32>>: |
| 38 | + | 21| 1|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) { |
| 39 | + | 22| 1| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); |
29 | 40 | | 23| 1|}
|
30 | 41 | ------------------
|
31 |
| - | uses_crate::used_crate::used_twice_generic_function::<&str>: |
32 |
| - | 21| 1|pub fn used_twice_generic_function<T: Debug>(arg: T) { |
33 |
| - | 22| 1| println!("used_twice_generic_function with {:?}", arg); |
| 42 | + | used_crate::used_only_from_this_lib_crate_generic_function::<&str>: |
| 43 | + | 21| 1|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) { |
| 44 | + | 22| 1| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); |
34 | 45 | | 23| 1|}
|
35 | 46 | ------------------
|
36 | 47 | 24| |
|
37 |
| - 25| 0|pub fn unused_generic_function<T: Debug>(arg: T) { |
38 |
| - 26| 0| println!("unused_generic_function with {:?}", arg); |
39 |
| - 27| 0|} |
| 48 | + 25| 2|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) { |
| 49 | + 26| 2| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); |
| 50 | + 27| 2|} |
| 51 | + ------------------ |
| 52 | + | used_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>: |
| 53 | + | 25| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) { |
| 54 | + | 26| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); |
| 55 | + | 27| 1|} |
| 56 | + ------------------ |
| 57 | + | used_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>: |
| 58 | + | 25| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) { |
| 59 | + | 26| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); |
| 60 | + | 27| 1|} |
| 61 | + ------------------ |
40 | 62 | 28| |
|
41 |
| - 29| 0|pub fn unused_function() { |
42 |
| - 30| 0| let is_true = std::env::args().len() == 1; |
43 |
| - 31| 0| let mut countdown = 2; |
44 |
| - 32| 0| if !is_true { |
45 |
| - 33| 0| countdown = 20; |
46 |
| - 34| 0| } |
| 63 | + 29| 2|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) { |
| 64 | + 30| 2| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); |
| 65 | + 31| 2|} |
| 66 | + 32| | |
| 67 | + 33| 0|pub fn unused_generic_function<T: Debug>(arg: T) { |
| 68 | + 34| 0| println!("unused_generic_function with {:?}", arg); |
47 | 69 | 35| 0|}
|
48 | 70 | 36| |
|
49 |
| - 37| 0|fn unused_private_function() { |
| 71 | + 37| 0|pub fn unused_function() { |
50 | 72 | 38| 0| let is_true = std::env::args().len() == 1;
|
51 | 73 | 39| 0| let mut countdown = 2;
|
52 | 74 | 40| 0| if !is_true {
|
53 | 75 | 41| 0| countdown = 20;
|
54 | 76 | 42| 0| }
|
55 | 77 | 43| 0|}
|
| 78 | + 44| | |
| 79 | + 45| 0|fn unused_private_function() { |
| 80 | + 46| 0| let is_true = std::env::args().len() == 1; |
| 81 | + 47| 0| let mut countdown = 2; |
| 82 | + 48| 0| if !is_true { |
| 83 | + 49| 0| countdown = 20; |
| 84 | + 50| 0| } |
| 85 | + 51| 0|} |
| 86 | + 52| | |
| 87 | + 53| 1|fn use_this_lib_crate() { |
| 88 | + 54| 1| used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs"); |
| 89 | + 55| 1| used_with_same_type_from_bin_crate_and_lib_crate_generic_function( |
| 90 | + 56| 1| "used from library used_crate.rs", |
| 91 | + 57| 1| ); |
| 92 | + 58| 1| let some_vec = vec![5, 6, 7, 8]; |
| 93 | + 59| 1| used_only_from_this_lib_crate_generic_function(some_vec); |
| 94 | + 60| 1| used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs"); |
| 95 | + 61| 1|} |
| 96 | + ------------------ |
| 97 | + | Unexecuted instantiation: used_crate::use_this_lib_crate |
| 98 | + ------------------ |
| 99 | + 62| | |
| 100 | + 63| |// FIXME(#79651): `used_from_bin_crate_and_lib_crate_generic_function()` is covered and executed |
| 101 | + 64| |// `2` times, but the coverage output also shows (at the bottom of the coverage report): |
| 102 | + 65| |// ------------------ |
| 103 | + 66| |// | Unexecuted instantiation: <some function name here> |
| 104 | + 67| |// ------------------ |
| 105 | + 68| |// |
| 106 | + 69| |// Note, the function name shown in the error seems to change depending on the structure of the |
| 107 | + 70| |// code, for some reason, including: |
| 108 | + 71| |// |
| 109 | + 72| |// * used_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str> |
| 110 | + 73| |// * used_crate::use_this_lib_crate |
| 111 | + 74| |// |
| 112 | + 75| |// The `Unexecuted instantiation` error may be related to more than one generic function. Since the |
| 113 | + 76| |// reporting is not consistent, it may not be obvious if there are multiple problems here; however, |
| 114 | + 77| |// `used_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>` (which I have seen |
| 115 | + 78| |// with this error) is the only generic function missing instantiaion coverage counts. |
| 116 | + 79| |// |
| 117 | + 80| |// The `&str` variant was called from within this `lib` crate, and the `bin` crate also calls this |
| 118 | + 81| |// function, but with `T` type `&Vec<i32>`. |
| 119 | + 82| |// |
| 120 | + 83| |// I believe the reason is that one or both crates are generating `Zero` counters for what it |
| 121 | + 84| |// believes are "Unreachable" instantiations, but those instantiations are counted from the |
| 122 | + 85| |// coverage map in the other crate. |
| 123 | + 86| |// |
| 124 | + 87| |// See `add_unreachable_coverage()` in `mapgen.rs` for more on how these `Zero` counters are added |
| 125 | + 88| |// for what the funciton believes are `DefId`s that did not get codegenned. I suspect the issue |
| 126 | + 89| |// may be related to this process, but this needs to be confirmed. It may not be possible to know |
| 127 | + 90| |// for sure if a function is truly unused and should be reported with `Zero` coverage if it may |
| 128 | + 91| |// still get used from an external crate. (Something to look at: If the `DefId` in MIR corresponds |
| 129 | + 92| |// _only_ to the generic function without type parameters, is the `DefId` in the codegenned set, |
| 130 | + 93| |// instantiated with one of the type parameters (in either or both crates) a *different* `DefId`? |
| 131 | + 94| |// If so, `add_unreachable_coverage()` would assume the MIR `DefId` was uncovered, and would add |
| 132 | + 95| |// unreachable coverage. |
| 133 | + 96| |// |
| 134 | + 97| |// I didn't think they could be different, but if they can, we would need to find the `DefId` for |
| 135 | + 98| |// the generic function MIR and include it in the set of "codegenned" DefIds if any instantiation |
| 136 | + 99| |// of that generic function does exist. |
| 137 | + 100| |// |
| 138 | + 101| |// Note, however, for `used_with_same_type_from_bin_crate_and_lib_crate_generic_function()` both |
| 139 | + 102| |// crates use this function with the same type variant. The function does not have multiple |
| 140 | + 103| |// instantiations, so the coverage analysis is not confused. No "Unexecuted instantiations" errors |
| 141 | + 104| |// are reported. |
56 | 142 |
|
0 commit comments