From d96f351fa36d31f2b95b1cd2ad37ceaed3d395a8 Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Tue, 1 Dec 2020 23:01:26 -0800 Subject: Addressed feedback from 2020-12-01 Added one more test (two files) showing coverage of generics and unused functions across crates. Created and referenced new Issues, as requested. Added comments. Added a note about the possible effects of compiler options on LLVM coverage maps. --- .../compiler-flags/source-based-code-coverage.md | 2 + .../expected_export_coverage.async.json | 52 ++-- .../expected_export_coverage.uses_crate.json | 85 ++++++ .../expected_show_coverage.async.txt | 74 ++--- .../expected_show_coverage.partial_eq.txt | 15 + .../expected_show_coverage.uses_crate.txt | 69 +++++ .../expected_show_coverage_counters.async.txt | 81 ++--- .../expected_show_coverage_counters.uses_crate.txt | 80 +++++ ...E-{closure#3}.-------.InstrumentCoverage.0.html | 4 +- ...utor-block_on.-------.InstrumentCoverage.0.html | 326 ++++++++++----------- ...m-{closure#0}.-------.InstrumentCoverage.0.html | 79 +++++ .../async.m.-------.InstrumentCoverage.0.html | 74 +++++ .../async.main.-------.InstrumentCoverage.0.html | 213 ++++++++------ ...es_crate.main.-------.InstrumentCoverage.0.html | 151 ++++++++++ ...used_function.-------.InstrumentCoverage.0.html | 119 ++++++++ ...eric_function.-------.InstrumentCoverage.0.html | 133 +++++++++ ...vate_function.-------.InstrumentCoverage.0.html | 119 ++++++++ ...used_function.-------.InstrumentCoverage.0.html | 113 +++++++ ...eric_function.-------.InstrumentCoverage.0.html | 133 +++++++++ ...eric_function.-------.InstrumentCoverage.0.html | 133 +++++++++ src/test/run-make-fulldeps/coverage/async.rs | 3 + src/test/run-make-fulldeps/coverage/partial_eq.rs | 15 + .../run-make-fulldeps/coverage/used_crate/mod.rs | 43 +++ src/test/run-make-fulldeps/coverage/uses_crate.rs | 10 + 24 files changed, 1767 insertions(+), 359 deletions(-) create mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.uses_crate.json create mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.uses_crate.txt create mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.m-{closure#0}.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.m.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.main.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-unused_function.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-unused_generic_function.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-unused_private_function.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-used_function.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-used_generic_function.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-used_twice_generic_function.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage/used_crate/mod.rs create mode 100644 src/test/run-make-fulldeps/coverage/uses_crate.rs (limited to 'src') diff --git a/src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md b/src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md index 95c2450ae57..9930bc67cd5 100644 --- a/src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md +++ b/src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md @@ -76,6 +76,8 @@ $ RUSTC=$HOME/rust/build/x86_64-unknown-linux-gnu/stage1/bin/rustc \ cargo build --example formatjson5 ``` +Note that some compiler options, combined with `-Zinstrument-coverage`, can produce LLVM IR and/or linked binaries that are incompatible with LLVM coverage maps. For example, coverage requires references to actual functions in LLVM IR. If any covered function is optimized out, the coverage tools may not be able to process the coverage results. If you need to pass additional options, with coverage enabled, test them early, to confirm you will get the coverage results you expect. + ## Running the instrumented binary to generate raw coverage profiling data In the previous example, `cargo` generated the coverage-instrumented binary `formatjson5`: diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.async.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.async.json index 4cc6ea39425..794a2e38253 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.async.json +++ b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.async.json @@ -6,50 +6,50 @@ "filename": "../coverage/async.rs", "summary": { "functions": { - "count": 16, - "covered": 15, - "percent": 93.75 + "count": 17, + "covered": 16, + "percent": 94.11764705882352 }, "instantiations": { - "count": 16, - "covered": 15, - "percent": 93.75 + "count": 17, + "covered": 16, + "percent": 94.11764705882352 }, "lines": { - "count": 102, - "covered": 75, - "percent": 73.52941176470588 + "count": 105, + "covered": 77, + "percent": 73.33333333333333 }, "regions": { - "count": 76, - "covered": 35, - "notcovered": 41, - "percent": 46.05263157894737 + "count": 78, + "covered": 36, + "notcovered": 42, + "percent": 46.15384615384615 } } } ], "totals": { "functions": { - "count": 16, - "covered": 15, - "percent": 93.75 + "count": 17, + "covered": 16, + "percent": 94.11764705882352 }, "instantiations": { - "count": 16, - "covered": 15, - "percent": 93.75 + "count": 17, + "covered": 16, + "percent": 94.11764705882352 }, "lines": { - "count": 102, - "covered": 75, - "percent": 73.52941176470588 + "count": 105, + "covered": 77, + "percent": 73.33333333333333 }, "regions": { - "count": 76, - "covered": 35, - "notcovered": 41, - "percent": 46.05263157894737 + "count": 78, + "covered": 36, + "notcovered": 42, + "percent": 46.15384615384615 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.uses_crate.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.uses_crate.json new file mode 100644 index 00000000000..6189c7b7b64 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.uses_crate.json @@ -0,0 +1,85 @@ +{ + "data": [ + { + "files": [ + { + "filename": "../coverage/used_crate/mod.rs", + "summary": { + "functions": { + "count": 3, + "covered": 3, + "percent": 100 + }, + "instantiations": { + "count": 4, + "covered": 4, + "percent": 100 + }, + "lines": { + "count": 31, + "covered": 14, + "percent": 45.16129032258064 + }, + "regions": { + "count": 16, + "covered": 6, + "notcovered": 10, + "percent": 37.5 + } + } + }, + { + "filename": "../coverage/uses_crate.rs", + "summary": { + "functions": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "instantiations": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "lines": { + "count": 6, + "covered": 6, + "percent": 100 + }, + "regions": { + "count": 1, + "covered": 1, + "notcovered": 0, + "percent": 100 + } + } + } + ], + "totals": { + "functions": { + "count": 4, + "covered": 4, + "percent": 100 + }, + "instantiations": { + "count": 5, + "covered": 5, + "percent": 100 + }, + "lines": { + "count": 37, + "covered": 20, + "percent": 54.054054054054056 + }, + "regions": { + "count": 17, + "covered": 7, + "notcovered": 10, + "percent": 41.17647058823529 + } + } + } + ], + "type": "llvm.coverage.json.export", + "version": "2.0.1" +} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async.txt index f6d02891eea..5c9dc0d22b5 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async.txt @@ -93,39 +93,43 @@ 88| | } 89| 1|} 90| | - 91| 1|fn main() { - 92| 1| let _ = g(10); - 93| 1| let _ = h(9); - 94| 1| let mut future = Box::pin(i(8)); - 95| 1| j(7); - 96| 1| l(6); - 97| 1| executor::block_on(future.as_mut()); - 98| 1|} - 99| | - 100| |mod executor { - 101| | use core::{ - 102| | future::Future, - 103| | pin::Pin, - 104| | task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, - 105| | }; - 106| | - 107| 1| pub fn block_on(mut future: F) -> F::Output { - 108| 1| let mut future = unsafe { Pin::new_unchecked(&mut future) }; - 109| 1| - 110| 1| static VTABLE: RawWakerVTable = RawWakerVTable::new( - 111| 1| |_| unimplemented!("clone"), - 112| 1| |_| unimplemented!("wake"), - 113| 1| |_| unimplemented!("wake_by_ref"), - 114| 1| |_| (), - 115| 1| ); - 116| 1| let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; - 117| 1| let mut context = Context::from_waker(&waker); - 118| | - 119| | loop { - 120| 1| if let Poll::Ready(val) = future.as_mut().poll(&mut context) { - 121| 1| break val; - 122| 0| } - 123| | } - 124| 1| } - 125| |} + 91| 1|async fn m(x: u8) -> u8 { x - 1 } + ^0 + 92| | + 93| 1|fn main() { + 94| 1| let _ = g(10); + 95| 1| let _ = h(9); + 96| 1| let mut future = Box::pin(i(8)); + 97| 1| j(7); + 98| 1| l(6); + 99| 1| let _ = m(5); + 100| 1| executor::block_on(future.as_mut()); + 101| 1|} + 102| | + 103| |mod executor { + 104| | use core::{ + 105| | future::Future, + 106| | pin::Pin, + 107| | task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, + 108| | }; + 109| | + 110| 1| pub fn block_on(mut future: F) -> F::Output { + 111| 1| let mut future = unsafe { Pin::new_unchecked(&mut future) }; + 112| 1| + 113| 1| static VTABLE: RawWakerVTable = RawWakerVTable::new( + 114| 1| |_| unimplemented!("clone"), + 115| 1| |_| unimplemented!("wake"), + 116| 1| |_| unimplemented!("wake_by_ref"), + 117| 1| |_| (), + 118| 1| ); + 119| 1| let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; + 120| 1| let mut context = Context::from_waker(&waker); + 121| | + 122| | loop { + 123| 1| if let Poll::Ready(val) = future.as_mut().poll(&mut context) { + 124| 1| break val; + 125| 0| } + 126| | } + 127| 1| } + 128| |} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.partial_eq.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.partial_eq.txt index c05cb36cd02..0fe124f12d9 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.partial_eq.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.partial_eq.txt @@ -45,4 +45,19 @@ 44| |`function_source_hash` without a code region, if necessary. 45| | 46| |*/ + 47| | + 48| |// FIXME(#79626): The derived traits get coverage, which is great, but some of the traits appear + 49| |// to get two coverage execution counts at different positions: + 50| |// + 51| |// ```text + 52| |// 4| 2|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] + 53| |// ^0 ^0 ^0 ^0 ^1 ^0 ^0^0 + 54| |// ```text + 55| |// + 56| |// `PartialEq`, `PartialOrd`, and `Ord` (and possibly `Eq`, if the trait name was longer than 2 + 57| |// characters) have counts at their first and last characters. + 58| |// + 59| |// Why is this? Why does `PartialOrd` have two values (1 and 0)? This must mean we are checking + 60| |// distinct coverages, so maybe we don't want to eliminate one of them. Should we merge them? + 61| |// If merged, do we lose some information? diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt new file mode 100644 index 00000000000..81b355a29ac --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt @@ -0,0 +1,69 @@ +../coverage/used_crate/mod.rs: + 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| used_twice_generic_function("some str"); + 15| 1|} + 16| | + 17| 1|pub fn used_generic_function(arg: T) { + 18| 1| println!("used_generic_function with {:?}", arg); + 19| 1|} + 20| | + 21| 2|pub fn used_twice_generic_function(arg: T) { + 22| 2| println!("used_twice_generic_function with {:?}", arg); + 23| 2|} + ------------------ + | uses_crate::used_crate::used_twice_generic_function::>: + | 21| 1|pub fn used_twice_generic_function(arg: T) { + | 22| 1| println!("used_twice_generic_function with {:?}", arg); + | 23| 1|} + ------------------ + | uses_crate::used_crate::used_twice_generic_function::<&str>: + | 21| 1|pub fn used_twice_generic_function(arg: T) { + | 22| 1| println!("used_twice_generic_function with {:?}", arg); + | 23| 1|} + ------------------ + 24| | + 25| 0|pub fn unused_generic_function(arg: T) { + 26| 0| println!("unused_generic_function with {:?}", arg); + 27| 0|} + 28| | + 29| 0|pub fn unused_function() { + 30| 0| let is_true = std::env::args().len() == 1; + 31| 0| let mut countdown = 2; + 32| 0| if !is_true { + 33| 0| countdown = 20; + 34| 0| } + 35| 0|} + 36| | + 37| 0|fn unused_private_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|} + +../coverage/uses_crate.rs: + 1| |#![allow(unused_assignments, unused_variables)] + 2| | + 3| |mod used_crate; + 4| | + 5| 1|fn main() { + 6| 1| used_crate::used_function(); + 7| 1| let some_vec = vec![1, 2, 3, 4]; + 8| 1| used_crate::used_generic_function(&some_vec); + 9| 1| used_crate::used_twice_generic_function(some_vec); + 10| 1|} + diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.async.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.async.txt index ce6ee3b1ed8..2fac0fea84b 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.async.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.async.txt @@ -26,18 +26,18 @@ Counter in file 0 77:14 -> 77:16, 0 Counter in file 0 78:14 -> 78:16, 0 Counter in file 0 79:14 -> 79:16, 0 Counter in file 0 81:1 -> 81:2, 0 +Counter in file 0 91:25 -> 91:34, 0 Counter in file 0 5:1 -> 5:25, #1 -Counter in file 0 21:1 -> 21:23, #1 -Counter in file 0 17:20 -> 17:21, #1 -Counter in file 0 67:5 -> 67:23, #1 -Counter in file 0 38:1 -> 38:19, #1 -Counter in file 0 13:20 -> 13:21, #1 -Counter in file 0 29:1 -> 29:22, #1 -Counter in file 0 91:1 -> 98:2, #1 Counter in file 0 5:25 -> 6:14, #1 Counter in file 0 7:9 -> 7:10, #2 Counter in file 0 9:9 -> 9:10, (#1 - #2) Counter in file 0 11:1 -> 11:2, (#2 + (#1 - #2)) +Counter in file 0 21:1 -> 21:23, #1 +Counter in file 0 67:5 -> 67:23, #1 +Counter in file 0 38:1 -> 38:19, #1 +Counter in file 0 29:1 -> 29:22, #1 +Counter in file 0 93:1 -> 101:2, #1 +Counter in file 0 91:1 -> 91:25, #1 Counter in file 0 38:19 -> 42:12, #1 Counter in file 0 43:9 -> 43:10, #3 Counter in file 0 43:14 -> 43:18, (#1 + 0) @@ -53,6 +53,7 @@ Counter in file 0 51:5 -> 52:18, #1 Counter in file 0 53:13 -> 53:14, #2 Counter in file 0 63:13 -> 63:14, (#1 - #2) Counter in file 0 65:5 -> 65:6, (#2 + (#1 - #2)) +Counter in file 0 17:20 -> 17:21, #1 Counter in file 0 49:1 -> 68:12, #1 Counter in file 0 69:9 -> 69:10, #2 Counter in file 0 69:14 -> 69:27, (#1 + 0) @@ -68,17 +69,18 @@ Counter in file 0 86:14 -> 86:16, #2 Counter in file 0 87:14 -> 87:16, #3 Counter in file 0 89:1 -> 89:2, (#3 + (#2 + (#1 - (#3 + #2)))) Counter in file 0 17:1 -> 17:20, #1 +Counter in file 0 13:20 -> 13:21, #1 Counter in file 0 66:5 -> 66:23, #1 -Counter in file 0 107:5 -> 117:54, #1 -Counter in file 0 120:32 -> 120:35, ((#1 + #2) - #2) -Counter in file 0 120:39 -> 120:73, (#1 + #2) -Counter in file 0 121:23 -> 121:26, (((#1 + #2) - #2) + 0) -Counter in file 0 122:14 -> 122:15, #2 -Counter in file 0 124:5 -> 124:6, (((#1 + #2) - #2) + 0) -Counter in file 0 114:17 -> 114:19, #1 Counter in file 0 17:9 -> 17:10, #1 Counter in file 0 17:9 -> 17:10, #1 +Counter in file 0 117:17 -> 117:19, #1 Counter in file 0 17:9 -> 17:10, #1 +Counter in file 0 110:5 -> 120:54, #1 +Counter in file 0 123:32 -> 123:35, ((#1 + #2) - #2) +Counter in file 0 123:39 -> 123:73, (#1 + #2) +Counter in file 0 124:23 -> 124:26, (((#1 + #2) - #2) + 0) +Counter in file 0 125:14 -> 125:15, #2 +Counter in file 0 127:5 -> 127:6, (((#1 + #2) - #2) + 0) Emitting segments for file: ../coverage/async.rs Combined regions: 5:1 -> 5:25 (count=1) @@ -149,14 +151,16 @@ Combined regions: 86:14 -> 86:16 (count=0) 87:14 -> 87:16 (count=1) 89:1 -> 89:2 (count=1) - 91:1 -> 98:2 (count=1) - 107:5 -> 117:54 (count=1) - 114:17 -> 114:19 (count=1) - 120:32 -> 120:35 (count=1) - 120:39 -> 120:73 (count=1) - 121:23 -> 121:26 (count=1) - 122:14 -> 122:15 (count=0) - 124:5 -> 124:6 (count=1) + 91:1 -> 91:25 (count=1) + 91:25 -> 91:34 (count=0) + 93:1 -> 101:2 (count=1) + 110:5 -> 120:54 (count=1) + 117:17 -> 117:19 (count=1) + 123:32 -> 123:35 (count=1) + 123:39 -> 123:73 (count=1) + 124:23 -> 124:26 (count=1) + 125:14 -> 125:15 (count=0) + 127:5 -> 127:6 (count=1) Segment at 5:1 (count = 1), RegionEntry Segment at 5:25 (count = 1), RegionEntry Segment at 6:14 (count = 0), Skipped @@ -287,18 +291,21 @@ Segment at 87:16 (count = 0), Skipped Segment at 89:1 (count = 1), RegionEntry Segment at 89:2 (count = 0), Skipped Segment at 91:1 (count = 1), RegionEntry -Segment at 98:2 (count = 0), Skipped -Segment at 107:5 (count = 1), RegionEntry -Segment at 114:17 (count = 1), RegionEntry -Segment at 114:19 (count = 1) -Segment at 117:54 (count = 0), Skipped -Segment at 120:32 (count = 1), RegionEntry -Segment at 120:35 (count = 0), Skipped -Segment at 120:39 (count = 1), RegionEntry -Segment at 120:73 (count = 0), Skipped -Segment at 121:23 (count = 1), RegionEntry -Segment at 121:26 (count = 0), Skipped -Segment at 122:14 (count = 0), RegionEntry -Segment at 122:15 (count = 0), Skipped -Segment at 124:5 (count = 1), RegionEntry -Segment at 124:6 (count = 0), Skipped +Segment at 91:25 (count = 0), RegionEntry +Segment at 91:34 (count = 0), Skipped +Segment at 93:1 (count = 1), RegionEntry +Segment at 101:2 (count = 0), Skipped +Segment at 110:5 (count = 1), RegionEntry +Segment at 117:17 (count = 1), RegionEntry +Segment at 117:19 (count = 1) +Segment at 120:54 (count = 0), Skipped +Segment at 123:32 (count = 1), RegionEntry +Segment at 123:35 (count = 0), Skipped +Segment at 123:39 (count = 1), RegionEntry +Segment at 123:73 (count = 0), Skipped +Segment at 124:23 (count = 1), RegionEntry +Segment at 124:26 (count = 0), Skipped +Segment at 125:14 (count = 0), RegionEntry +Segment at 125:15 (count = 0), Skipped +Segment at 127:5 (count = 1), RegionEntry +Segment at 127:6 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.uses_crate.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.uses_crate.txt new file mode 100644 index 00000000000..8901019f191 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.uses_crate.txt @@ -0,0 +1,80 @@ +Counter in file 0 17:1 -> 19:2, #1 +Counter in file 0 25:1 -> 27:2, 0 +Counter in file 0 29:1 -> 32:16, 0 +Counter in file 0 32:17 -> 34:6, 0 +Counter in file 0 34:6 -> 34:7, 0 +Counter in file 0 35:1 -> 35:2, 0 +Counter in file 0 37:1 -> 40:16, 0 +Counter in file 0 40:17 -> 42:6, 0 +Counter in file 0 42:6 -> 42:7, 0 +Counter in file 0 43:1 -> 43:2, 0 +Counter in file 0 5:1 -> 5:24, #1 +Counter in file 0 9:9 -> 11:15, (#1 + 0) +Counter in file 0 11:16 -> 13:6, #2 +Counter in file 0 13:6 -> 13:7, (#1 - #2) +Counter in file 0 14:5 -> 15:2, (#2 + (#1 - #2)) +Counter in file 0 21:1 -> 23:2, #1 +Counter in file 0 21:1 -> 23:2, #1 +Counter in file 0 5:1 -> 10:2, #1 +Emitting segments for file: ../coverage/used_crate/mod.rs +Combined regions: + 5:1 -> 5:24 (count=1) + 9:9 -> 11:15 (count=1) + 11:16 -> 13:6 (count=1) + 13:6 -> 13:7 (count=0) + 14:5 -> 15:2 (count=1) + 17:1 -> 19:2 (count=1) + 21:1 -> 23:2 (count=2) + 25:1 -> 27:2 (count=0) + 29:1 -> 32:16 (count=0) + 32:17 -> 34:6 (count=0) + 34:6 -> 34:7 (count=0) + 35:1 -> 35:2 (count=0) + 37:1 -> 40:16 (count=0) + 40:17 -> 42:6 (count=0) + 42:6 -> 42:7 (count=0) + 43:1 -> 43:2 (count=0) +Segment at 5:1 (count = 1), RegionEntry +Segment at 5:24 (count = 0), Skipped +Segment at 9:9 (count = 1), RegionEntry +Segment at 11:15 (count = 0), Skipped +Segment at 11:16 (count = 1), RegionEntry +Segment at 13:6 (count = 0), RegionEntry +Segment at 13:7 (count = 0), Skipped +Segment at 14:5 (count = 1), RegionEntry +Segment at 15:2 (count = 0), Skipped +Segment at 17:1 (count = 1), RegionEntry +Segment at 19:2 (count = 0), Skipped +Segment at 21:1 (count = 2), RegionEntry +Segment at 23:2 (count = 0), Skipped +Segment at 25:1 (count = 0), RegionEntry +Segment at 27:2 (count = 0), Skipped +Segment at 29:1 (count = 0), RegionEntry +Segment at 32:16 (count = 0), Skipped +Segment at 32:17 (count = 0), RegionEntry +Segment at 34:6 (count = 0), RegionEntry +Segment at 34:7 (count = 0), Skipped +Segment at 35:1 (count = 0), RegionEntry +Segment at 35:2 (count = 0), Skipped +Segment at 37:1 (count = 0), RegionEntry +Segment at 40:16 (count = 0), Skipped +Segment at 40:17 (count = 0), RegionEntry +Segment at 42:6 (count = 0), RegionEntry +Segment at 42:7 (count = 0), Skipped +Segment at 43:1 (count = 0), RegionEntry +Segment at 43:2 (count = 0), Skipped +Emitting segments for function: _RINvNtCs4fqI2P2rA04_10uses_crate10used_crate27used_twice_generic_functionINtNtCs3QflaznQylx_5alloc3vec3VeclEEB4_ +Combined regions: + 21:1 -> 23:2 (count=1) +Segment at 21:1 (count = 1), RegionEntry +Segment at 23:2 (count = 0), Skipped +Emitting segments for function: _RINvNtCs4fqI2P2rA04_10uses_crate10used_crate27used_twice_generic_functionReEB4_ +Combined regions: + 21:1 -> 23:2 (count=1) +Segment at 21:1 (count = 1), RegionEntry +Segment at 23:2 (count = 0), Skipped +Emitting segments for file: ../coverage/uses_crate.rs +Combined regions: + 5:1 -> 10:2 (count=1) +Segment at 5:1 (count = 1), RegionEntry +Segment at 10:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on-VTABLE-{closure#3}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on-VTABLE-{closure#3}.-------.InstrumentCoverage.0.html index 996c537225d..ef2fe7d0682 100644 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on-VTABLE-{closure#3}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on-VTABLE-{closure#3}.-------.InstrumentCoverage.0.html @@ -69,7 +69,7 @@ For revisions in Pull Requests (PR): -
|_| @0⦊()⦉@0
+
|_| @0⦊()⦉@0
diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on.-------.InstrumentCoverage.0.html index 0c597d40de0..81310c8cb25 100644 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on.-------.InstrumentCoverage.0.html @@ -69,171 +69,171 @@ For revisions in Pull Requests (PR): -
@0,1,2,3,4,5⦊pub fn block_on<F: Future>(mut future: F) -> F::Output { - let mut future = unsafe { Pin::new_unchecked(&mut future) }; - - static VTABLE: RawWakerVTable = RawWakerVTable::new( - |_| unimplemented!("clone"), - |_| unimplemented!("wake"), - |_| unimplemented!("wake_by_ref"), - |_| (), - ); - let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; - let mut context = Context::from_waker(&waker)⦉@0,1,2,3,4,5; +
@0,1,2,3,4,5⦊pub fn block_on<F: Future>(mut future: F) -> F::Output { + let mut future = unsafe { Pin::new_unchecked(&mut future) }; + + static VTABLE: RawWakerVTable = RawWakerVTable::new( + |_| unimplemented!("clone"), + |_| unimplemented!("wake"), + |_| unimplemented!("wake_by_ref"), + |_| (), + ); + let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; + let mut context = Context::from_waker(&waker)⦉@0,1,2,3,4,5; loop { - if let Poll::Ready(@10,12,14,15,16,17⦊val⦉@10,12,14,15,16,17) = @6,7,8,9⦊future.as_mut().poll(&mut context)⦉@6,7,8,9 { - break @10,12,14,15,16,17⦊val⦉@10,12,14,15,16,17; - }@11,13⦊⦉@11,13 + if let Poll::Ready(@10,12,14,15,16,17⦊val⦉@10,12,14,15,16,17) = @6,7,8,9⦊future.as_mut().poll(&mut context)⦉@6,7,8,9 { + break @10,12,14,15,16,17⦊val⦉@10,12,14,15,16,17; + }@11,13⦊⦉@11,13 } - }@10,12,14,15,16,17⦊⦉@10,12,14,15,16,17
+ }@10,12,14,15,16,17⦊⦉@10,12,14,15,16,17
diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.m-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.m-{closure#0}.-------.InstrumentCoverage.0.html new file mode 100644 index 00000000000..9cf86ce34a0 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.m-{closure#0}.-------.InstrumentCoverage.0.html @@ -0,0 +1,79 @@ + + + + +async.m-{closure#0} - Coverage Spans + + + +
@0,1⦊{ x - 1 }⦉@0,1
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.m.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.m.-------.InstrumentCoverage.0.html new file mode 100644 index 00000000000..04412c1d994 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.m.-------.InstrumentCoverage.0.html @@ -0,0 +1,74 @@ + + + + +async.m - Coverage Spans + + + +
@0,1⦊async fn m(x: u8) -> u8 ⦉@0,1{ x - 1 }
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.main.-------.InstrumentCoverage.0.html index 2b0eb4f43c7..313a36ed6c2 100644 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.main.-------.InstrumentCoverage.0.html @@ -69,101 +69,122 @@ For revisions in Pull Requests (PR): -
@0,1,2,3,4,5,6,7,8,9,10,11⦊fn main() { - let _ = g(10); - let _ = h(9); - let mut future = Box::pin(i(8)); - j(7); - l(6); - executor::block_on(future.as_mut()); -}⦉@0,1,2,3,4,5,6,7,8,9,10,11
+
@0,1,2,3,4,5,6,7,8,9,10,11,12,13⦊fn main() { + let _ = g(10); + let _ = h(9); + let mut future = Box::pin(i(8)); + j(7); + l(6); + let _ = m(5); + executor::block_on(future.as_mut()); +}⦉@0,1,2,3,4,5,6,7,8,9,10,11,12,13
diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.main.-------.InstrumentCoverage.0.html new file mode 100644 index 00000000000..52c99558de6 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.main.-------.InstrumentCoverage.0.html @@ -0,0 +1,151 @@ + + + + +uses_crate.main - Coverage Spans + + + +
@0,1,2,3,4,5,6,7⦊fn main() { + used_crate::used_function(); + let some_vec = vec![1, 2, 3, 4]; + used_crate::used_generic_function(&some_vec); + used_crate::used_twice_generic_function(some_vec); +}⦉@0,1,2,3,4,5,6,7
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-unused_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-unused_function.-------.InstrumentCoverage.0.html new file mode 100644 index 00000000000..42ba0458349 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-unused_function.-------.InstrumentCoverage.0.html @@ -0,0 +1,119 @@ + + + + +uses_crate.used_crate-unused_function - Coverage Spans + + + +
@0,1,2,3⦊pub fn unused_function() { + let is_true = std::env::args().len() == 1; + let mut countdown = 2; + if !is_true⦉@0,1,2,3 @4,6⦊{ + countdown = 20; + }⦉@4,6@5⦊⦉@5 +}@7⦊⦉@7
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-unused_generic_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-unused_generic_function.-------.InstrumentCoverage.0.html new file mode 100644 index 00000000000..d89963a32ce --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-unused_generic_function.-------.InstrumentCoverage.0.html @@ -0,0 +1,133 @@ + + + + +uses_crate.used_crate-unused_generic_function - Coverage Spans + + + +
@0,1,2,3,4⦊pub fn unused_generic_function<T: Debug>(arg: T) { + println!("unused_generic_function with {:?}", arg); +}⦉@0,1,2,3,4
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-unused_private_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-unused_private_function.-------.InstrumentCoverage.0.html new file mode 100644 index 00000000000..10e71152c53 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-unused_private_function.-------.InstrumentCoverage.0.html @@ -0,0 +1,119 @@ + + + + +uses_crate.used_crate-unused_private_function - Coverage Spans + + + +
@0,1,2,3⦊fn unused_private_function() { + let is_true = std::env::args().len() == 1; + let mut countdown = 2; + if !is_true⦉@0,1,2,3 @4,6⦊{ + countdown = 20; + }⦉@4,6@5⦊⦉@5 +}@7⦊⦉@7
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-used_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-used_function.-------.InstrumentCoverage.0.html new file mode 100644 index 00000000000..15dce97e742 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-used_function.-------.InstrumentCoverage.0.html @@ -0,0 +1,113 @@ + + + + +uses_crate.used_crate-used_function - Coverage Spans + + + +
@0,1,2,3⦊pub fn used_function() ⦉@0,1,2,3{ + // 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 @0,1,2,3⦊is_true = std::env::args().len() == 1; + let mut countdown = 0; + if is_true⦉@0,1,2,3 @4,6⦊{ + countdown = 10; + }⦉@4,6@5⦊⦉@5 + @7,8⦊used_twice_generic_function("some str"); +}⦉@7,8
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-used_generic_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-used_generic_function.-------.InstrumentCoverage.0.html new file mode 100644 index 00000000000..e47ed0b3817 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-used_generic_function.-------.InstrumentCoverage.0.html @@ -0,0 +1,133 @@ + + + + +uses_crate.used_crate-used_generic_function - Coverage Spans + + + +
@0,1,2,3,4⦊pub fn used_generic_function<T: Debug>(arg: T) { + println!("used_generic_function with {:?}", arg); +}⦉@0,1,2,3,4
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-used_twice_generic_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-used_twice_generic_function.-------.InstrumentCoverage.0.html new file mode 100644 index 00000000000..ef63db45cc0 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.used_crate-used_twice_generic_function.-------.InstrumentCoverage.0.html @@ -0,0 +1,133 @@ + + + + +uses_crate.used_crate-used_twice_generic_function - Coverage Spans + + + +
@0,1,2,3,4⦊pub fn used_twice_generic_function<T: Debug>(arg: T) { + println!("used_twice_generic_function with {:?}", arg); +}⦉@0,1,2,3,4
+ + diff --git a/src/test/run-make-fulldeps/coverage/async.rs b/src/test/run-make-fulldeps/coverage/async.rs index fcf6f76944e..491d2746543 100644 --- a/src/test/run-make-fulldeps/coverage/async.rs +++ b/src/test/run-make-fulldeps/coverage/async.rs @@ -88,12 +88,15 @@ fn l(x: u8) { } } +async fn m(x: u8) -> u8 { x - 1 } + fn main() { let _ = g(10); let _ = h(9); let mut future = Box::pin(i(8)); j(7); l(6); + let _ = m(5); executor::block_on(future.as_mut()); } diff --git a/src/test/run-make-fulldeps/coverage/partial_eq.rs b/src/test/run-make-fulldeps/coverage/partial_eq.rs index 547026f9502..7d265ba66a4 100644 --- a/src/test/run-make-fulldeps/coverage/partial_eq.rs +++ b/src/test/run-make-fulldeps/coverage/partial_eq.rs @@ -44,3 +44,18 @@ one expression, which is allowed, but the `function_source_hash` was only passed `function_source_hash` without a code region, if necessary. */ + +// FIXME(#79626): The derived traits get coverage, which is great, but some of the traits appear +// to get two coverage execution counts at different positions: +// +// ```text +// 4| 2|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +// ^0 ^0 ^0 ^0 ^1 ^0 ^0^0 +// ```text +// +// `PartialEq`, `PartialOrd`, and `Ord` (and possibly `Eq`, if the trait name was longer than 2 +// characters) have counts at their first and last characters. +// +// Why is this? Why does `PartialOrd` have two values (1 and 0)? This must mean we are checking +// distinct coverages, so maybe we don't want to eliminate one of them. Should we merge them? +// If merged, do we lose some information? diff --git a/src/test/run-make-fulldeps/coverage/used_crate/mod.rs b/src/test/run-make-fulldeps/coverage/used_crate/mod.rs new file mode 100644 index 00000000000..825eff4d352 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage/used_crate/mod.rs @@ -0,0 +1,43 @@ +#![allow(unused_assignments, unused_variables)] + +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; + } + used_twice_generic_function("some str"); +} + +pub fn used_generic_function(arg: T) { + println!("used_generic_function with {:?}", arg); +} + +pub fn used_twice_generic_function(arg: T) { + println!("used_twice_generic_function with {:?}", arg); +} + +pub fn unused_generic_function(arg: T) { + println!("unused_generic_function with {:?}", arg); +} + +pub fn unused_function() { + let is_true = std::env::args().len() == 1; + let mut countdown = 2; + if !is_true { + countdown = 20; + } +} + +fn unused_private_function() { + let is_true = std::env::args().len() == 1; + let mut countdown = 2; + if !is_true { + countdown = 20; + } +} diff --git a/src/test/run-make-fulldeps/coverage/uses_crate.rs b/src/test/run-make-fulldeps/coverage/uses_crate.rs new file mode 100644 index 00000000000..473d43217a9 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage/uses_crate.rs @@ -0,0 +1,10 @@ +#![allow(unused_assignments, unused_variables)] + +mod used_crate; + +fn main() { + used_crate::used_function(); + let some_vec = vec![1, 2, 3, 4]; + used_crate::used_generic_function(&some_vec); + used_crate::used_twice_generic_function(some_vec); +} -- cgit 1.4.1-3-g733a5