coverage: Anonymize line numbers in run-coverage
test snapshots
This makes the test snapshots less sensitive to lines being added/removed.
This commit is contained in:
parent
07438b0928
commit
bfb16545a3
46 changed files with 2672 additions and 2655 deletions
|
@ -18,6 +18,7 @@ use crate::ColorConfig;
|
|||
use regex::{Captures, Regex};
|
||||
use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::env;
|
||||
|
@ -664,6 +665,7 @@ impl<'test> TestCx<'test> {
|
|||
|
||||
fn normalize_coverage_output(&self, coverage: &str) -> Result<String, String> {
|
||||
let normalized = self.normalize_output(coverage, &[]);
|
||||
let normalized = Self::anonymize_coverage_line_numbers(&normalized);
|
||||
|
||||
let mut lines = normalized.lines().collect::<Vec<_>>();
|
||||
|
||||
|
@ -674,6 +676,21 @@ impl<'test> TestCx<'test> {
|
|||
Ok(joined_lines)
|
||||
}
|
||||
|
||||
/// Replace line numbers in coverage reports with the placeholder `LL`,
|
||||
/// so that the tests are less sensitive to lines being added/removed.
|
||||
fn anonymize_coverage_line_numbers(coverage: &str) -> Cow<'_, str> {
|
||||
// The coverage reporter prints line numbers at the start of a line.
|
||||
// They are truncated or left-padded to occupy exactly 5 columns.
|
||||
// (`LineNumberColumnWidth` in `SourceCoverageViewText.cpp`.)
|
||||
// A pipe character `|` appears immediately after the final digit.
|
||||
//
|
||||
// Line numbers that appear inside expansion/instantiation subviews
|
||||
// have an additional prefix of ` |` for each nesting level.
|
||||
static LINE_NUMBER_RE: Lazy<Regex> =
|
||||
Lazy::new(|| Regex::new(r"(?m:^)(?<prefix>(?: \|)*) *[0-9]+\|").unwrap());
|
||||
LINE_NUMBER_RE.replace_all(coverage, "$prefix LL|")
|
||||
}
|
||||
|
||||
/// Coverage reports can describe multiple source files, separated by
|
||||
/// blank lines. The order of these files is unpredictable (since it
|
||||
/// depends on implementation details), so we need to sort the file
|
||||
|
|
|
@ -1,115 +1,115 @@
|
|||
$DIR/auxiliary/doctest_crate.rs:
|
||||
1| |/// A function run only from within doctests
|
||||
2| 3|pub fn fn_run_in_doctests(conditional: usize) {
|
||||
3| 3| match conditional {
|
||||
4| 1| 1 => assert_eq!(1, 1), // this is run,
|
||||
5| 1| 2 => assert_eq!(1, 1), // this,
|
||||
6| 1| 3 => assert_eq!(1, 1), // and this too
|
||||
7| 0| _ => assert_eq!(1, 2), // however this is not
|
||||
8| | }
|
||||
9| 3|}
|
||||
LL| |/// A function run only from within doctests
|
||||
LL| 3|pub fn fn_run_in_doctests(conditional: usize) {
|
||||
LL| 3| match conditional {
|
||||
LL| 1| 1 => assert_eq!(1, 1), // this is run,
|
||||
LL| 1| 2 => assert_eq!(1, 1), // this,
|
||||
LL| 1| 3 => assert_eq!(1, 1), // and this too
|
||||
LL| 0| _ => assert_eq!(1, 2), // however this is not
|
||||
LL| | }
|
||||
LL| 3|}
|
||||
|
||||
$DIR/doctest.rs:
|
||||
1| |//! This test ensures that code from doctests is properly re-mapped.
|
||||
2| |//! See <https://github.com/rust-lang/rust/issues/79417> for more info.
|
||||
3| |//!
|
||||
4| |//! Just some random code:
|
||||
5| 1|//! ```
|
||||
6| 1|//! if true {
|
||||
7| |//! // this is executed!
|
||||
8| 1|//! assert_eq!(1, 1);
|
||||
9| |//! } else {
|
||||
10| |//! // this is not!
|
||||
11| 0|//! assert_eq!(1, 2);
|
||||
12| |//! }
|
||||
13| 1|//! ```
|
||||
14| |//!
|
||||
15| |//! doctest testing external code:
|
||||
16| |//! ```
|
||||
17| 1|//! extern crate doctest_crate;
|
||||
18| 1|//! doctest_crate::fn_run_in_doctests(1);
|
||||
19| 1|//! ```
|
||||
20| |//!
|
||||
21| |//! doctest returning a result:
|
||||
22| 1|//! ```
|
||||
23| 2|//! #[derive(Debug, PartialEq)]
|
||||
LL| |//! This test ensures that code from doctests is properly re-mapped.
|
||||
LL| |//! See <https://github.com/rust-lang/rust/issues/79417> for more info.
|
||||
LL| |//!
|
||||
LL| |//! Just some random code:
|
||||
LL| 1|//! ```
|
||||
LL| 1|//! if true {
|
||||
LL| |//! // this is executed!
|
||||
LL| 1|//! assert_eq!(1, 1);
|
||||
LL| |//! } else {
|
||||
LL| |//! // this is not!
|
||||
LL| 0|//! assert_eq!(1, 2);
|
||||
LL| |//! }
|
||||
LL| 1|//! ```
|
||||
LL| |//!
|
||||
LL| |//! doctest testing external code:
|
||||
LL| |//! ```
|
||||
LL| 1|//! extern crate doctest_crate;
|
||||
LL| 1|//! doctest_crate::fn_run_in_doctests(1);
|
||||
LL| 1|//! ```
|
||||
LL| |//!
|
||||
LL| |//! doctest returning a result:
|
||||
LL| 1|//! ```
|
||||
LL| 2|//! #[derive(Debug, PartialEq)]
|
||||
^1
|
||||
24| 1|//! struct SomeError {
|
||||
25| 1|//! msg: String,
|
||||
26| 1|//! }
|
||||
27| 1|//! let mut res = Err(SomeError { msg: String::from("a message") });
|
||||
28| 1|//! if res.is_ok() {
|
||||
29| 0|//! res?;
|
||||
30| |//! } else {
|
||||
31| 1|//! if *res.as_ref().unwrap_err() == *res.as_ref().unwrap_err() {
|
||||
32| 1|//! println!("{:?}", res);
|
||||
33| 1|//! }
|
||||
LL| 1|//! struct SomeError {
|
||||
LL| 1|//! msg: String,
|
||||
LL| 1|//! }
|
||||
LL| 1|//! let mut res = Err(SomeError { msg: String::from("a message") });
|
||||
LL| 1|//! if res.is_ok() {
|
||||
LL| 0|//! res?;
|
||||
LL| |//! } else {
|
||||
LL| 1|//! if *res.as_ref().unwrap_err() == *res.as_ref().unwrap_err() {
|
||||
LL| 1|//! println!("{:?}", res);
|
||||
LL| 1|//! }
|
||||
^0
|
||||
34| 1|//! if *res.as_ref().unwrap_err() == *res.as_ref().unwrap_err() {
|
||||
35| 1|//! res = Ok(1);
|
||||
36| 1|//! }
|
||||
LL| 1|//! if *res.as_ref().unwrap_err() == *res.as_ref().unwrap_err() {
|
||||
LL| 1|//! res = Ok(1);
|
||||
LL| 1|//! }
|
||||
^0
|
||||
37| 1|//! res = Ok(0);
|
||||
38| |//! }
|
||||
39| |//! // need to be explicit because rustdoc cant infer the return type
|
||||
40| 1|//! Ok::<(), SomeError>(())
|
||||
41| 1|//! ```
|
||||
42| |//!
|
||||
43| |//! doctest with custom main:
|
||||
44| |//! ```
|
||||
45| 1|//! fn some_func() {
|
||||
46| 1|//! println!("called some_func()");
|
||||
47| 1|//! }
|
||||
48| |//!
|
||||
49| 0|//! #[derive(Debug)]
|
||||
50| |//! struct SomeError;
|
||||
51| |//!
|
||||
52| |//! extern crate doctest_crate;
|
||||
53| |//!
|
||||
54| 1|//! fn doctest_main() -> Result<(), SomeError> {
|
||||
55| 1|//! some_func();
|
||||
56| 1|//! doctest_crate::fn_run_in_doctests(2);
|
||||
57| 1|//! Ok(())
|
||||
58| 1|//! }
|
||||
59| |//!
|
||||
60| |//! // this `main` is not shown as covered, as it clashes with all the other
|
||||
61| |//! // `main` functions that were automatically generated for doctests
|
||||
62| |//! fn main() -> Result<(), SomeError> {
|
||||
63| |//! doctest_main()
|
||||
64| |//! }
|
||||
65| |//! ```
|
||||
66| |// aux-build:doctest_crate.rs
|
||||
67| |/// doctest attached to fn testing external code:
|
||||
68| |/// ```
|
||||
69| 1|/// extern crate doctest_crate;
|
||||
70| 1|/// doctest_crate::fn_run_in_doctests(3);
|
||||
71| 1|/// ```
|
||||
72| |///
|
||||
73| 1|fn main() {
|
||||
74| 1| if true {
|
||||
75| 1| assert_eq!(1, 1);
|
||||
76| | } else {
|
||||
77| 0| assert_eq!(1, 2);
|
||||
78| | }
|
||||
79| 1|}
|
||||
80| |
|
||||
81| |// FIXME(Swatinem): Fix known issue that coverage code region columns need to be offset by the
|
||||
82| |// doc comment line prefix (`///` or `//!`) and any additional indent (before or after the doc
|
||||
83| |// comment characters). This test produces `llvm-cov show` results demonstrating the problem.
|
||||
84| |//
|
||||
85| |// One of the above tests now includes: `derive(Debug, PartialEq)`, producing an `llvm-cov show`
|
||||
86| |// result with a distinct count for `Debug`, denoted by `^1`, but the caret points to the wrong
|
||||
87| |// column. Similarly, the `if` blocks without `else` blocks show `^0`, which should point at, or
|
||||
88| |// one character past, the `if` block's closing brace. In both cases, these are most likely off
|
||||
89| |// by the number of characters stripped from the beginning of each doc comment line: indent
|
||||
90| |// whitespace, if any, doc comment prefix (`//!` in this case) and (I assume) one space character
|
||||
91| |// (?). Note, when viewing `llvm-cov show` results in `--color` mode, the column offset errors are
|
||||
92| |// more pronounced, and show up in more places, with background color used to show some distinct
|
||||
93| |// code regions with different coverage counts.
|
||||
94| |//
|
||||
95| |// NOTE: Since the doc comment line prefix may vary, one possible solution is to replace each
|
||||
96| |// character stripped from the beginning of doc comment lines with a space. This will give coverage
|
||||
97| |// results the correct column offsets, and I think it should compile correctly, but I don't know
|
||||
98| |// what affect it might have on diagnostic messages from the compiler, and whether anyone would care
|
||||
99| |// if the indentation changed. I don't know if there is a more viable solution.
|
||||
LL| 1|//! res = Ok(0);
|
||||
LL| |//! }
|
||||
LL| |//! // need to be explicit because rustdoc cant infer the return type
|
||||
LL| 1|//! Ok::<(), SomeError>(())
|
||||
LL| 1|//! ```
|
||||
LL| |//!
|
||||
LL| |//! doctest with custom main:
|
||||
LL| |//! ```
|
||||
LL| 1|//! fn some_func() {
|
||||
LL| 1|//! println!("called some_func()");
|
||||
LL| 1|//! }
|
||||
LL| |//!
|
||||
LL| 0|//! #[derive(Debug)]
|
||||
LL| |//! struct SomeError;
|
||||
LL| |//!
|
||||
LL| |//! extern crate doctest_crate;
|
||||
LL| |//!
|
||||
LL| 1|//! fn doctest_main() -> Result<(), SomeError> {
|
||||
LL| 1|//! some_func();
|
||||
LL| 1|//! doctest_crate::fn_run_in_doctests(2);
|
||||
LL| 1|//! Ok(())
|
||||
LL| 1|//! }
|
||||
LL| |//!
|
||||
LL| |//! // this `main` is not shown as covered, as it clashes with all the other
|
||||
LL| |//! // `main` functions that were automatically generated for doctests
|
||||
LL| |//! fn main() -> Result<(), SomeError> {
|
||||
LL| |//! doctest_main()
|
||||
LL| |//! }
|
||||
LL| |//! ```
|
||||
LL| |// aux-build:doctest_crate.rs
|
||||
LL| |/// doctest attached to fn testing external code:
|
||||
LL| |/// ```
|
||||
LL| 1|/// extern crate doctest_crate;
|
||||
LL| 1|/// doctest_crate::fn_run_in_doctests(3);
|
||||
LL| 1|/// ```
|
||||
LL| |///
|
||||
LL| 1|fn main() {
|
||||
LL| 1| if true {
|
||||
LL| 1| assert_eq!(1, 1);
|
||||
LL| | } else {
|
||||
LL| 0| assert_eq!(1, 2);
|
||||
LL| | }
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| |// FIXME(Swatinem): Fix known issue that coverage code region columns need to be offset by the
|
||||
LL| |// doc comment line prefix (`///` or `//!`) and any additional indent (before or after the doc
|
||||
LL| |// comment characters). This test produces `llvm-cov show` results demonstrating the problem.
|
||||
LL| |//
|
||||
LL| |// One of the above tests now includes: `derive(Debug, PartialEq)`, producing an `llvm-cov show`
|
||||
LL| |// result with a distinct count for `Debug`, denoted by `^1`, but the caret points to the wrong
|
||||
LL| |// column. Similarly, the `if` blocks without `else` blocks show `^0`, which should point at, or
|
||||
LL| |// one character past, the `if` block's closing brace. In both cases, these are most likely off
|
||||
LL| |// by the number of characters stripped from the beginning of each doc comment line: indent
|
||||
LL| |// whitespace, if any, doc comment prefix (`//!` in this case) and (I assume) one space character
|
||||
LL| |// (?). Note, when viewing `llvm-cov show` results in `--color` mode, the column offset errors are
|
||||
LL| |// more pronounced, and show up in more places, with background color used to show some distinct
|
||||
LL| |// code regions with different coverage counts.
|
||||
LL| |//
|
||||
LL| |// NOTE: Since the doc comment line prefix may vary, one possible solution is to replace each
|
||||
LL| |// character stripped from the beginning of doc comment lines with a space. This will give coverage
|
||||
LL| |// results the correct column offsets, and I think it should compile correctly, but I don't know
|
||||
LL| |// what affect it might have on diagnostic messages from the compiler, and whether anyone would care
|
||||
LL| |// if the indentation changed. I don't know if there is a more viable solution.
|
||||
|
||||
|
|
|
@ -1,69 +1,69 @@
|
|||
1| |#![feature(c_unwind)]
|
||||
2| |#![allow(unused_assignments)]
|
||||
3| |
|
||||
4| 12|extern "C" fn might_abort(should_abort: bool) {
|
||||
5| 12| if should_abort {
|
||||
6| 0| println!("aborting...");
|
||||
7| 0| panic!("panics and aborts");
|
||||
8| 12| } else {
|
||||
9| 12| println!("Don't Panic");
|
||||
10| 12| }
|
||||
11| 12|}
|
||||
12| |
|
||||
13| 1|fn main() -> Result<(), u8> {
|
||||
14| 1| let mut countdown = 10;
|
||||
15| 11| while countdown > 0 {
|
||||
16| 10| if countdown < 5 {
|
||||
17| 4| might_abort(false);
|
||||
18| 6| }
|
||||
19| | // See discussion (below the `Notes` section) on coverage results for the closing brace.
|
||||
20| 10| if countdown < 5 { might_abort(false); } // Counts for different regions on one line.
|
||||
LL| |#![feature(c_unwind)]
|
||||
LL| |#![allow(unused_assignments)]
|
||||
LL| |
|
||||
LL| 12|extern "C" fn might_abort(should_abort: bool) {
|
||||
LL| 12| if should_abort {
|
||||
LL| 0| println!("aborting...");
|
||||
LL| 0| panic!("panics and aborts");
|
||||
LL| 12| } else {
|
||||
LL| 12| println!("Don't Panic");
|
||||
LL| 12| }
|
||||
LL| 12|}
|
||||
LL| |
|
||||
LL| 1|fn main() -> Result<(), u8> {
|
||||
LL| 1| let mut countdown = 10;
|
||||
LL| 11| while countdown > 0 {
|
||||
LL| 10| if countdown < 5 {
|
||||
LL| 4| might_abort(false);
|
||||
LL| 6| }
|
||||
LL| | // See discussion (below the `Notes` section) on coverage results for the closing brace.
|
||||
LL| 10| if countdown < 5 { might_abort(false); } // Counts for different regions on one line.
|
||||
^4 ^6
|
||||
21| | // For the following example, the closing brace is the last character on the line.
|
||||
22| | // This shows the character after the closing brace is highlighted, even if that next
|
||||
23| | // character is a newline.
|
||||
24| 10| if countdown < 5 { might_abort(false); }
|
||||
LL| | // For the following example, the closing brace is the last character on the line.
|
||||
LL| | // This shows the character after the closing brace is highlighted, even if that next
|
||||
LL| | // character is a newline.
|
||||
LL| 10| if countdown < 5 { might_abort(false); }
|
||||
^4 ^6
|
||||
25| 10| countdown -= 1;
|
||||
26| | }
|
||||
27| 1| Ok(())
|
||||
28| 1|}
|
||||
29| |
|
||||
30| |// Notes:
|
||||
31| |// 1. Compare this program and its coverage results to those of the similar tests
|
||||
32| |// `panic_unwind.rs` and `try_error_result.rs`.
|
||||
33| |// 2. This test confirms the coverage generated when a program includes `UnwindAction::Terminate`.
|
||||
34| |// 3. The test does not invoke the abort. By executing to a successful completion, the coverage
|
||||
35| |// results show where the program did and did not execute.
|
||||
36| |// 4. If the program actually aborted, the coverage counters would not be saved (which "works as
|
||||
37| |// intended"). Coverage results would show no executed coverage regions.
|
||||
38| |// 6. If `should_abort` is `true` and the program aborts, the program exits with a `132` status
|
||||
39| |// (on Linux at least).
|
||||
40| |
|
||||
41| |/*
|
||||
42| |
|
||||
43| |Expect the following coverage results:
|
||||
44| |
|
||||
45| |```text
|
||||
46| | 16| 11| while countdown > 0 {
|
||||
47| | 17| 10| if countdown < 5 {
|
||||
48| | 18| 4| might_abort(false);
|
||||
49| | 19| 6| }
|
||||
50| |```
|
||||
51| |
|
||||
52| |This is actually correct.
|
||||
53| |
|
||||
54| |The condition `countdown < 5` executed 10 times (10 loop iterations).
|
||||
55| |
|
||||
56| |It evaluated to `true` 4 times, and executed the `might_abort()` call.
|
||||
57| |
|
||||
58| |It skipped the body of the `might_abort()` call 6 times. If an `if` does not include an explicit
|
||||
59| |`else`, the coverage implementation injects a counter, at the character immediately after the `if`s
|
||||
60| |closing brace, to count the "implicit" `else`. This is the only way to capture the coverage of the
|
||||
61| |non-true condition.
|
||||
62| |
|
||||
63| |As another example of why this is important, say the condition was `countdown < 50`, which is always
|
||||
64| |`true`. In that case, we wouldn't have a test for what happens if `might_abort()` is not called.
|
||||
65| |The closing brace would have a count of `0`, highlighting the missed coverage.
|
||||
66| |*/
|
||||
LL| 10| countdown -= 1;
|
||||
LL| | }
|
||||
LL| 1| Ok(())
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| |// Notes:
|
||||
LL| |// 1. Compare this program and its coverage results to those of the similar tests
|
||||
LL| |// `panic_unwind.rs` and `try_error_result.rs`.
|
||||
LL| |// 2. This test confirms the coverage generated when a program includes `UnwindAction::Terminate`.
|
||||
LL| |// 3. The test does not invoke the abort. By executing to a successful completion, the coverage
|
||||
LL| |// results show where the program did and did not execute.
|
||||
LL| |// 4. If the program actually aborted, the coverage counters would not be saved (which "works as
|
||||
LL| |// intended"). Coverage results would show no executed coverage regions.
|
||||
LL| |// 6. If `should_abort` is `true` and the program aborts, the program exits with a `132` status
|
||||
LL| |// (on Linux at least).
|
||||
LL| |
|
||||
LL| |/*
|
||||
LL| |
|
||||
LL| |Expect the following coverage results:
|
||||
LL| |
|
||||
LL| |```text
|
||||
LL| | 16| 11| while countdown > 0 {
|
||||
LL| | 17| 10| if countdown < 5 {
|
||||
LL| | 18| 4| might_abort(false);
|
||||
LL| | 19| 6| }
|
||||
LL| |```
|
||||
LL| |
|
||||
LL| |This is actually correct.
|
||||
LL| |
|
||||
LL| |The condition `countdown < 5` executed 10 times (10 loop iterations).
|
||||
LL| |
|
||||
LL| |It evaluated to `true` 4 times, and executed the `might_abort()` call.
|
||||
LL| |
|
||||
LL| |It skipped the body of the `might_abort()` call 6 times. If an `if` does not include an explicit
|
||||
LL| |`else`, the coverage implementation injects a counter, at the character immediately after the `if`s
|
||||
LL| |closing brace, to count the "implicit" `else`. This is the only way to capture the coverage of the
|
||||
LL| |non-true condition.
|
||||
LL| |
|
||||
LL| |As another example of why this is important, say the condition was `countdown < 50`, which is always
|
||||
LL| |`true`. In that case, we wouldn't have a test for what happens if `might_abort()` is not called.
|
||||
LL| |The closing brace would have a count of `0`, highlighting the missed coverage.
|
||||
LL| |*/
|
||||
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
1| |#![allow(unused_assignments)]
|
||||
2| |// failure-status: 101
|
||||
3| |
|
||||
4| 4|fn might_fail_assert(one_plus_one: u32) {
|
||||
5| 4| println!("does 1 + 1 = {}?", one_plus_one);
|
||||
6| 4| assert_eq!(1 + 1, one_plus_one, "the argument was wrong");
|
||||
LL| |#![allow(unused_assignments)]
|
||||
LL| |// failure-status: 101
|
||||
LL| |
|
||||
LL| 4|fn might_fail_assert(one_plus_one: u32) {
|
||||
LL| 4| println!("does 1 + 1 = {}?", one_plus_one);
|
||||
LL| 4| assert_eq!(1 + 1, one_plus_one, "the argument was wrong");
|
||||
^1
|
||||
7| 3|}
|
||||
8| |
|
||||
9| 1|fn main() -> Result<(),u8> {
|
||||
10| 1| let mut countdown = 10;
|
||||
11| 11| while countdown > 0 {
|
||||
12| 11| if countdown == 1 {
|
||||
13| 1| might_fail_assert(3);
|
||||
14| 10| } else if countdown < 5 {
|
||||
15| 3| might_fail_assert(2);
|
||||
16| 6| }
|
||||
17| 10| countdown -= 1;
|
||||
18| | }
|
||||
19| 0| Ok(())
|
||||
20| 0|}
|
||||
21| |
|
||||
22| |// Notes:
|
||||
23| |// 1. Compare this program and its coverage results to those of the very similar test
|
||||
24| |// `panic_unwind.rs`, and similar tests `abort.rs` and `try_error_result.rs`.
|
||||
25| |// 2. This test confirms the coverage generated when a program passes or fails an `assert!()` or
|
||||
26| |// related `assert_*!()` macro.
|
||||
27| |// 3. Notably, the `assert` macros *do not* generate `TerminatorKind::Assert`. The macros produce
|
||||
28| |// conditional expressions, `TerminatorKind::SwitchInt` branches, and a possible call to
|
||||
29| |// `begin_panic_fmt()` (that begins a panic unwind, if the assertion test fails).
|
||||
30| |// 4. `TerminatoKind::Assert` is, however, also present in the MIR generated for this test
|
||||
31| |// (and in many other coverage tests). The `Assert` terminator is typically generated by the
|
||||
32| |// Rust compiler to check for runtime failures, such as numeric overflows.
|
||||
LL| 3|}
|
||||
LL| |
|
||||
LL| 1|fn main() -> Result<(),u8> {
|
||||
LL| 1| let mut countdown = 10;
|
||||
LL| 11| while countdown > 0 {
|
||||
LL| 11| if countdown == 1 {
|
||||
LL| 1| might_fail_assert(3);
|
||||
LL| 10| } else if countdown < 5 {
|
||||
LL| 3| might_fail_assert(2);
|
||||
LL| 6| }
|
||||
LL| 10| countdown -= 1;
|
||||
LL| | }
|
||||
LL| 0| Ok(())
|
||||
LL| 0|}
|
||||
LL| |
|
||||
LL| |// Notes:
|
||||
LL| |// 1. Compare this program and its coverage results to those of the very similar test
|
||||
LL| |// `panic_unwind.rs`, and similar tests `abort.rs` and `try_error_result.rs`.
|
||||
LL| |// 2. This test confirms the coverage generated when a program passes or fails an `assert!()` or
|
||||
LL| |// related `assert_*!()` macro.
|
||||
LL| |// 3. Notably, the `assert` macros *do not* generate `TerminatorKind::Assert`. The macros produce
|
||||
LL| |// conditional expressions, `TerminatorKind::SwitchInt` branches, and a possible call to
|
||||
LL| |// `begin_panic_fmt()` (that begins a panic unwind, if the assertion test fails).
|
||||
LL| |// 4. `TerminatoKind::Assert` is, however, also present in the MIR generated for this test
|
||||
LL| |// (and in many other coverage tests). The `Assert` terminator is typically generated by the
|
||||
LL| |// Rust compiler to check for runtime failures, such as numeric overflows.
|
||||
|
||||
|
|
|
@ -1,139 +1,139 @@
|
|||
1| |#![allow(unused_assignments, dead_code)]
|
||||
2| |
|
||||
3| |// compile-flags: --edition=2018 -C opt-level=1
|
||||
4| |
|
||||
5| 1|async fn c(x: u8) -> u8 {
|
||||
6| 1| if x == 8 {
|
||||
7| 1| 1
|
||||
8| | } else {
|
||||
9| 0| 0
|
||||
10| | }
|
||||
11| 1|}
|
||||
12| |
|
||||
13| 0|async fn d() -> u8 { 1 }
|
||||
14| |
|
||||
15| 0|async fn e() -> u8 { 1 } // unused function; executor does not block on `g()`
|
||||
16| |
|
||||
17| 1|async fn f() -> u8 { 1 }
|
||||
18| |
|
||||
19| 0|async fn foo() -> [bool; 10] { [false; 10] } // unused function; executor does not block on `h()`
|
||||
20| |
|
||||
21| 1|pub async fn g(x: u8) {
|
||||
22| 0| match x {
|
||||
23| 0| y if e().await == y => (),
|
||||
24| 0| y if f().await == y => (),
|
||||
25| 0| _ => (),
|
||||
26| | }
|
||||
27| 0|}
|
||||
28| |
|
||||
29| 1|async fn h(x: usize) { // The function signature is counted when called, but the body is not
|
||||
30| 0| // executed (not awaited) so the open brace has a `0` count (at least when
|
||||
31| 0| // displayed with `llvm-cov show` in color-mode).
|
||||
32| 0| match x {
|
||||
33| 0| y if foo().await[y] => (),
|
||||
34| 0| _ => (),
|
||||
35| | }
|
||||
36| 0|}
|
||||
37| |
|
||||
38| 1|async fn i(x: u8) { // line coverage is 1, but there are 2 regions:
|
||||
39| 1| // (a) the function signature, counted when the function is called; and
|
||||
40| 1| // (b) the open brace for the function body, counted once when the body is
|
||||
41| 1| // executed asynchronously.
|
||||
42| 1| match x {
|
||||
43| 1| y if c(x).await == y + 1 => { d().await; }
|
||||
LL| |#![allow(unused_assignments, dead_code)]
|
||||
LL| |
|
||||
LL| |// compile-flags: --edition=2018 -C opt-level=1
|
||||
LL| |
|
||||
LL| 1|async fn c(x: u8) -> u8 {
|
||||
LL| 1| if x == 8 {
|
||||
LL| 1| 1
|
||||
LL| | } else {
|
||||
LL| 0| 0
|
||||
LL| | }
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| 0|async fn d() -> u8 { 1 }
|
||||
LL| |
|
||||
LL| 0|async fn e() -> u8 { 1 } // unused function; executor does not block on `g()`
|
||||
LL| |
|
||||
LL| 1|async fn f() -> u8 { 1 }
|
||||
LL| |
|
||||
LL| 0|async fn foo() -> [bool; 10] { [false; 10] } // unused function; executor does not block on `h()`
|
||||
LL| |
|
||||
LL| 1|pub async fn g(x: u8) {
|
||||
LL| 0| match x {
|
||||
LL| 0| y if e().await == y => (),
|
||||
LL| 0| y if f().await == y => (),
|
||||
LL| 0| _ => (),
|
||||
LL| | }
|
||||
LL| 0|}
|
||||
LL| |
|
||||
LL| 1|async fn h(x: usize) { // The function signature is counted when called, but the body is not
|
||||
LL| 0| // executed (not awaited) so the open brace has a `0` count (at least when
|
||||
LL| 0| // displayed with `llvm-cov show` in color-mode).
|
||||
LL| 0| match x {
|
||||
LL| 0| y if foo().await[y] => (),
|
||||
LL| 0| _ => (),
|
||||
LL| | }
|
||||
LL| 0|}
|
||||
LL| |
|
||||
LL| 1|async fn i(x: u8) { // line coverage is 1, but there are 2 regions:
|
||||
LL| 1| // (a) the function signature, counted when the function is called; and
|
||||
LL| 1| // (b) the open brace for the function body, counted once when the body is
|
||||
LL| 1| // executed asynchronously.
|
||||
LL| 1| match x {
|
||||
LL| 1| y if c(x).await == y + 1 => { d().await; }
|
||||
^0 ^0 ^0 ^0
|
||||
44| 1| y if f().await == y + 1 => (),
|
||||
LL| 1| y if f().await == y + 1 => (),
|
||||
^0 ^0 ^0
|
||||
45| 1| _ => (),
|
||||
46| | }
|
||||
47| 1|}
|
||||
48| |
|
||||
49| 1|fn j(x: u8) {
|
||||
50| 1| // non-async versions of `c()`, `d()`, and `f()` to make it similar to async `i()`.
|
||||
51| 1| fn c(x: u8) -> u8 {
|
||||
52| 1| if x == 8 {
|
||||
53| 1| 1 // This line appears covered, but the 1-character expression span covering the `1`
|
||||
LL| 1| _ => (),
|
||||
LL| | }
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| 1|fn j(x: u8) {
|
||||
LL| 1| // non-async versions of `c()`, `d()`, and `f()` to make it similar to async `i()`.
|
||||
LL| 1| fn c(x: u8) -> u8 {
|
||||
LL| 1| if x == 8 {
|
||||
LL| 1| 1 // This line appears covered, but the 1-character expression span covering the `1`
|
||||
^0
|
||||
54| 1| // is not executed. (`llvm-cov show` displays a `^0` below the `1` ). This is because
|
||||
55| 1| // `fn j()` executes the open brace for the function body, followed by the function's
|
||||
56| 1| // first executable statement, `match x`. Inner function declarations are not
|
||||
57| 1| // "visible" to the MIR for `j()`, so the code region counts all lines between the
|
||||
58| 1| // open brace and the first statement as executed, which is, in a sense, true.
|
||||
59| 1| // `llvm-cov show` overcomes this kind of situation by showing the actual counts
|
||||
60| 1| // of the enclosed coverages, (that is, the `1` expression was not executed, and
|
||||
61| 1| // accurately displays a `0`).
|
||||
62| 1| } else {
|
||||
63| 1| 0
|
||||
64| 1| }
|
||||
65| 1| }
|
||||
66| 1| fn d() -> u8 { 1 } // inner function is defined in-line, but the function is not executed
|
||||
LL| 1| // is not executed. (`llvm-cov show` displays a `^0` below the `1` ). This is because
|
||||
LL| 1| // `fn j()` executes the open brace for the function body, followed by the function's
|
||||
LL| 1| // first executable statement, `match x`. Inner function declarations are not
|
||||
LL| 1| // "visible" to the MIR for `j()`, so the code region counts all lines between the
|
||||
LL| 1| // open brace and the first statement as executed, which is, in a sense, true.
|
||||
LL| 1| // `llvm-cov show` overcomes this kind of situation by showing the actual counts
|
||||
LL| 1| // of the enclosed coverages, (that is, the `1` expression was not executed, and
|
||||
LL| 1| // accurately displays a `0`).
|
||||
LL| 1| } else {
|
||||
LL| 1| 0
|
||||
LL| 1| }
|
||||
LL| 1| }
|
||||
LL| 1| fn d() -> u8 { 1 } // inner function is defined in-line, but the function is not executed
|
||||
^0
|
||||
67| 1| fn f() -> u8 { 1 }
|
||||
68| 1| match x {
|
||||
69| 1| y if c(x) == y + 1 => { d(); }
|
||||
LL| 1| fn f() -> u8 { 1 }
|
||||
LL| 1| match x {
|
||||
LL| 1| y if c(x) == y + 1 => { d(); }
|
||||
^0 ^0
|
||||
70| 1| y if f() == y + 1 => (),
|
||||
LL| 1| y if f() == y + 1 => (),
|
||||
^0 ^0
|
||||
71| 1| _ => (),
|
||||
72| | }
|
||||
73| 1|}
|
||||
74| |
|
||||
75| 0|fn k(x: u8) { // unused function
|
||||
76| 0| match x {
|
||||
77| 0| 1 => (),
|
||||
78| 0| 2 => (),
|
||||
79| 0| _ => (),
|
||||
80| | }
|
||||
81| 0|}
|
||||
82| |
|
||||
83| 1|fn l(x: u8) {
|
||||
84| 1| match x {
|
||||
85| 0| 1 => (),
|
||||
86| 0| 2 => (),
|
||||
87| 1| _ => (),
|
||||
88| | }
|
||||
89| 1|}
|
||||
90| |
|
||||
91| 1|async fn m(x: u8) -> u8 { x - 1 }
|
||||
LL| 1| _ => (),
|
||||
LL| | }
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| 0|fn k(x: u8) { // unused function
|
||||
LL| 0| match x {
|
||||
LL| 0| 1 => (),
|
||||
LL| 0| 2 => (),
|
||||
LL| 0| _ => (),
|
||||
LL| | }
|
||||
LL| 0|}
|
||||
LL| |
|
||||
LL| 1|fn l(x: u8) {
|
||||
LL| 1| match x {
|
||||
LL| 0| 1 => (),
|
||||
LL| 0| 2 => (),
|
||||
LL| 1| _ => (),
|
||||
LL| | }
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| 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<F: Future>(mut future: F) -> F::Output {
|
||||
111| 1| let mut future = unsafe { Pin::new_unchecked(&mut future) };
|
||||
112| 1| use std::hint::unreachable_unchecked;
|
||||
113| 1| static VTABLE: RawWakerVTable = RawWakerVTable::new(
|
||||
114| 1| |_| unsafe { unreachable_unchecked() }, // clone
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| let _ = g(10);
|
||||
LL| 1| let _ = h(9);
|
||||
LL| 1| let mut future = Box::pin(i(8));
|
||||
LL| 1| j(7);
|
||||
LL| 1| l(6);
|
||||
LL| 1| let _ = m(5);
|
||||
LL| 1| executor::block_on(future.as_mut());
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| |mod executor {
|
||||
LL| | use core::{
|
||||
LL| | future::Future,
|
||||
LL| | pin::Pin,
|
||||
LL| | task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
|
||||
LL| | };
|
||||
LL| |
|
||||
LL| 1| pub fn block_on<F: Future>(mut future: F) -> F::Output {
|
||||
LL| 1| let mut future = unsafe { Pin::new_unchecked(&mut future) };
|
||||
LL| 1| use std::hint::unreachable_unchecked;
|
||||
LL| 1| static VTABLE: RawWakerVTable = RawWakerVTable::new(
|
||||
LL| 1| |_| unsafe { unreachable_unchecked() }, // clone
|
||||
^0
|
||||
115| 1| |_| unsafe { unreachable_unchecked() }, // wake
|
||||
LL| 1| |_| unsafe { unreachable_unchecked() }, // wake
|
||||
^0
|
||||
116| 1| |_| unsafe { unreachable_unchecked() }, // wake_by_ref
|
||||
LL| 1| |_| unsafe { unreachable_unchecked() }, // wake_by_ref
|
||||
^0
|
||||
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| |}
|
||||
LL| 1| |_| (),
|
||||
LL| 1| );
|
||||
LL| 1| let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
|
||||
LL| 1| let mut context = Context::from_waker(&waker);
|
||||
LL| |
|
||||
LL| | loop {
|
||||
LL| 1| if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
|
||||
LL| 1| break val;
|
||||
LL| 0| }
|
||||
LL| | }
|
||||
LL| 1| }
|
||||
LL| |}
|
||||
|
||||
|
|
|
@ -1,116 +1,116 @@
|
|||
1| |// compile-flags: --edition=2018
|
||||
2| |
|
||||
3| |use core::{
|
||||
4| | future::Future,
|
||||
5| | marker::Send,
|
||||
6| | pin::Pin,
|
||||
7| |};
|
||||
8| |
|
||||
9| 1|fn non_async_func() {
|
||||
10| 1| println!("non_async_func was covered");
|
||||
11| 1| let b = true;
|
||||
12| 1| if b {
|
||||
13| 1| println!("non_async_func println in block");
|
||||
14| 1| }
|
||||
LL| |// compile-flags: --edition=2018
|
||||
LL| |
|
||||
LL| |use core::{
|
||||
LL| | future::Future,
|
||||
LL| | marker::Send,
|
||||
LL| | pin::Pin,
|
||||
LL| |};
|
||||
LL| |
|
||||
LL| 1|fn non_async_func() {
|
||||
LL| 1| println!("non_async_func was covered");
|
||||
LL| 1| let b = true;
|
||||
LL| 1| if b {
|
||||
LL| 1| println!("non_async_func println in block");
|
||||
LL| 1| }
|
||||
^0
|
||||
15| 1|}
|
||||
16| |
|
||||
17| |
|
||||
18| |
|
||||
19| |
|
||||
20| 1|async fn async_func() {
|
||||
21| 1| println!("async_func was covered");
|
||||
22| 1| let b = true;
|
||||
23| 1| if b {
|
||||
24| 1| println!("async_func println in block");
|
||||
25| 1| }
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| |
|
||||
LL| |
|
||||
LL| |
|
||||
LL| 1|async fn async_func() {
|
||||
LL| 1| println!("async_func was covered");
|
||||
LL| 1| let b = true;
|
||||
LL| 1| if b {
|
||||
LL| 1| println!("async_func println in block");
|
||||
LL| 1| }
|
||||
^0
|
||||
26| 1|}
|
||||
27| |
|
||||
28| |
|
||||
29| |
|
||||
30| |
|
||||
31| 1|async fn async_func_just_println() {
|
||||
32| 1| println!("async_func_just_println was covered");
|
||||
33| 1|}
|
||||
34| |
|
||||
35| 1|fn main() {
|
||||
36| 1| println!("codecovsample::main");
|
||||
37| 1|
|
||||
38| 1| non_async_func();
|
||||
39| 1|
|
||||
40| 1| executor::block_on(async_func());
|
||||
41| 1| executor::block_on(async_func_just_println());
|
||||
42| 1|}
|
||||
43| |
|
||||
44| |mod executor {
|
||||
45| | use core::{
|
||||
46| | future::Future,
|
||||
47| | pin::Pin,
|
||||
48| | task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
|
||||
49| | };
|
||||
50| |
|
||||
51| 2| pub fn block_on<F: Future>(mut future: F) -> F::Output {
|
||||
52| 2| let mut future = unsafe { Pin::new_unchecked(&mut future) };
|
||||
53| 2| use std::hint::unreachable_unchecked;
|
||||
54| 2| static VTABLE: RawWakerVTable = RawWakerVTable::new(
|
||||
55| 2| |_| unsafe { unreachable_unchecked() }, // clone
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| |
|
||||
LL| |
|
||||
LL| |
|
||||
LL| 1|async fn async_func_just_println() {
|
||||
LL| 1| println!("async_func_just_println was covered");
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| println!("codecovsample::main");
|
||||
LL| 1|
|
||||
LL| 1| non_async_func();
|
||||
LL| 1|
|
||||
LL| 1| executor::block_on(async_func());
|
||||
LL| 1| executor::block_on(async_func_just_println());
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| |mod executor {
|
||||
LL| | use core::{
|
||||
LL| | future::Future,
|
||||
LL| | pin::Pin,
|
||||
LL| | task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
|
||||
LL| | };
|
||||
LL| |
|
||||
LL| 2| pub fn block_on<F: Future>(mut future: F) -> F::Output {
|
||||
LL| 2| let mut future = unsafe { Pin::new_unchecked(&mut future) };
|
||||
LL| 2| use std::hint::unreachable_unchecked;
|
||||
LL| 2| static VTABLE: RawWakerVTable = RawWakerVTable::new(
|
||||
LL| 2| |_| unsafe { unreachable_unchecked() }, // clone
|
||||
^0
|
||||
56| 2| |_| unsafe { unreachable_unchecked() }, // wake
|
||||
LL| 2| |_| unsafe { unreachable_unchecked() }, // wake
|
||||
^0
|
||||
57| 2| |_| unsafe { unreachable_unchecked() }, // wake_by_ref
|
||||
LL| 2| |_| unsafe { unreachable_unchecked() }, // wake_by_ref
|
||||
^0
|
||||
58| 2| |_| (),
|
||||
59| 2| );
|
||||
60| 2| let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
|
||||
61| 2| let mut context = Context::from_waker(&waker);
|
||||
62| |
|
||||
63| | loop {
|
||||
64| 2| if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
|
||||
65| 2| break val;
|
||||
66| 0| }
|
||||
67| | }
|
||||
68| 2| }
|
||||
LL| 2| |_| (),
|
||||
LL| 2| );
|
||||
LL| 2| let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
|
||||
LL| 2| let mut context = Context::from_waker(&waker);
|
||||
LL| |
|
||||
LL| | loop {
|
||||
LL| 2| if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
|
||||
LL| 2| break val;
|
||||
LL| 0| }
|
||||
LL| | }
|
||||
LL| 2| }
|
||||
------------------
|
||||
| async2::executor::block_on::<async2::async_func::{closure#0}>:
|
||||
| 51| 1| pub fn block_on<F: Future>(mut future: F) -> F::Output {
|
||||
| 52| 1| let mut future = unsafe { Pin::new_unchecked(&mut future) };
|
||||
| 53| 1| use std::hint::unreachable_unchecked;
|
||||
| 54| 1| static VTABLE: RawWakerVTable = RawWakerVTable::new(
|
||||
| 55| 1| |_| unsafe { unreachable_unchecked() }, // clone
|
||||
| 56| 1| |_| unsafe { unreachable_unchecked() }, // wake
|
||||
| 57| 1| |_| unsafe { unreachable_unchecked() }, // wake_by_ref
|
||||
| 58| 1| |_| (),
|
||||
| 59| 1| );
|
||||
| 60| 1| let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
|
||||
| 61| 1| let mut context = Context::from_waker(&waker);
|
||||
| 62| |
|
||||
| 63| | loop {
|
||||
| 64| 1| if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
|
||||
| 65| 1| break val;
|
||||
| 66| 0| }
|
||||
| 67| | }
|
||||
| 68| 1| }
|
||||
| LL| 1| pub fn block_on<F: Future>(mut future: F) -> F::Output {
|
||||
| LL| 1| let mut future = unsafe { Pin::new_unchecked(&mut future) };
|
||||
| LL| 1| use std::hint::unreachable_unchecked;
|
||||
| LL| 1| static VTABLE: RawWakerVTable = RawWakerVTable::new(
|
||||
| LL| 1| |_| unsafe { unreachable_unchecked() }, // clone
|
||||
| LL| 1| |_| unsafe { unreachable_unchecked() }, // wake
|
||||
| LL| 1| |_| unsafe { unreachable_unchecked() }, // wake_by_ref
|
||||
| LL| 1| |_| (),
|
||||
| LL| 1| );
|
||||
| LL| 1| let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
|
||||
| LL| 1| let mut context = Context::from_waker(&waker);
|
||||
| LL| |
|
||||
| LL| | loop {
|
||||
| LL| 1| if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
|
||||
| LL| 1| break val;
|
||||
| LL| 0| }
|
||||
| LL| | }
|
||||
| LL| 1| }
|
||||
------------------
|
||||
| async2::executor::block_on::<async2::async_func_just_println::{closure#0}>:
|
||||
| 51| 1| pub fn block_on<F: Future>(mut future: F) -> F::Output {
|
||||
| 52| 1| let mut future = unsafe { Pin::new_unchecked(&mut future) };
|
||||
| 53| 1| use std::hint::unreachable_unchecked;
|
||||
| 54| 1| static VTABLE: RawWakerVTable = RawWakerVTable::new(
|
||||
| 55| 1| |_| unsafe { unreachable_unchecked() }, // clone
|
||||
| 56| 1| |_| unsafe { unreachable_unchecked() }, // wake
|
||||
| 57| 1| |_| unsafe { unreachable_unchecked() }, // wake_by_ref
|
||||
| 58| 1| |_| (),
|
||||
| 59| 1| );
|
||||
| 60| 1| let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
|
||||
| 61| 1| let mut context = Context::from_waker(&waker);
|
||||
| 62| |
|
||||
| 63| | loop {
|
||||
| 64| 1| if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
|
||||
| 65| 1| break val;
|
||||
| 66| 0| }
|
||||
| 67| | }
|
||||
| 68| 1| }
|
||||
| LL| 1| pub fn block_on<F: Future>(mut future: F) -> F::Output {
|
||||
| LL| 1| let mut future = unsafe { Pin::new_unchecked(&mut future) };
|
||||
| LL| 1| use std::hint::unreachable_unchecked;
|
||||
| LL| 1| static VTABLE: RawWakerVTable = RawWakerVTable::new(
|
||||
| LL| 1| |_| unsafe { unreachable_unchecked() }, // clone
|
||||
| LL| 1| |_| unsafe { unreachable_unchecked() }, // wake
|
||||
| LL| 1| |_| unsafe { unreachable_unchecked() }, // wake_by_ref
|
||||
| LL| 1| |_| (),
|
||||
| LL| 1| );
|
||||
| LL| 1| let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
|
||||
| LL| 1| let mut context = Context::from_waker(&waker);
|
||||
| LL| |
|
||||
| LL| | loop {
|
||||
| LL| 1| if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
|
||||
| LL| 1| break val;
|
||||
| LL| 0| }
|
||||
| LL| | }
|
||||
| LL| 1| }
|
||||
------------------
|
||||
69| |}
|
||||
LL| |}
|
||||
|
||||
|
|
|
@ -1,222 +1,222 @@
|
|||
1| |#![allow(unused_assignments, unused_variables)]
|
||||
2| |// compile-flags: -C opt-level=2
|
||||
3| 1|fn main() { // ^^ fix described in rustc_middle/mir/mono.rs
|
||||
4| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
5| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
6| 1| // dependent conditions.
|
||||
7| 1| let is_true = std::env::args().len() == 1;
|
||||
8| 1| let is_false = ! is_true;
|
||||
9| 1|
|
||||
10| 1| let mut some_string = Some(String::from("the string content"));
|
||||
11| 1| println!(
|
||||
12| 1| "The string or alt: {}"
|
||||
13| 1| ,
|
||||
14| 1| some_string
|
||||
15| 1| .
|
||||
16| 1| unwrap_or_else
|
||||
17| 1| (
|
||||
18| 1| ||
|
||||
19| 0| {
|
||||
20| 0| let mut countdown = 0;
|
||||
21| 0| if is_false {
|
||||
22| 0| countdown = 10;
|
||||
23| 0| }
|
||||
24| 0| "alt string 1".to_owned()
|
||||
25| 1| }
|
||||
26| 1| )
|
||||
27| 1| );
|
||||
28| 1|
|
||||
29| 1| some_string = Some(String::from("the string content"));
|
||||
30| 1| let
|
||||
31| 1| a
|
||||
32| | =
|
||||
33| | ||
|
||||
34| 0| {
|
||||
35| 0| let mut countdown = 0;
|
||||
36| 0| if is_false {
|
||||
37| 0| countdown = 10;
|
||||
38| 0| }
|
||||
39| 0| "alt string 2".to_owned()
|
||||
40| 0| };
|
||||
41| 1| println!(
|
||||
42| 1| "The string or alt: {}"
|
||||
43| 1| ,
|
||||
44| 1| some_string
|
||||
45| 1| .
|
||||
46| 1| unwrap_or_else
|
||||
47| 1| (
|
||||
48| 1| a
|
||||
49| 1| )
|
||||
50| 1| );
|
||||
51| 1|
|
||||
52| 1| some_string = None;
|
||||
53| 1| println!(
|
||||
54| 1| "The string or alt: {}"
|
||||
55| 1| ,
|
||||
56| 1| some_string
|
||||
57| 1| .
|
||||
58| 1| unwrap_or_else
|
||||
59| 1| (
|
||||
60| 1| ||
|
||||
61| 1| {
|
||||
62| 1| let mut countdown = 0;
|
||||
63| 1| if is_false {
|
||||
64| 0| countdown = 10;
|
||||
65| 1| }
|
||||
66| 1| "alt string 3".to_owned()
|
||||
67| 1| }
|
||||
68| 1| )
|
||||
69| 1| );
|
||||
70| 1|
|
||||
71| 1| some_string = None;
|
||||
72| 1| let
|
||||
73| 1| a
|
||||
74| 1| =
|
||||
75| 1| ||
|
||||
76| 1| {
|
||||
77| 1| let mut countdown = 0;
|
||||
78| 1| if is_false {
|
||||
79| 0| countdown = 10;
|
||||
80| 1| }
|
||||
81| 1| "alt string 4".to_owned()
|
||||
82| 1| };
|
||||
83| 1| println!(
|
||||
84| 1| "The string or alt: {}"
|
||||
85| 1| ,
|
||||
86| 1| some_string
|
||||
87| 1| .
|
||||
88| 1| unwrap_or_else
|
||||
89| 1| (
|
||||
90| 1| a
|
||||
91| 1| )
|
||||
92| 1| );
|
||||
93| 1|
|
||||
94| 1| let
|
||||
95| 1| quote_closure
|
||||
96| 1| =
|
||||
97| 1| |val|
|
||||
98| 5| {
|
||||
99| 5| let mut countdown = 0;
|
||||
100| 5| if is_false {
|
||||
101| 0| countdown = 10;
|
||||
102| 5| }
|
||||
103| 5| format!("'{}'", val)
|
||||
104| 5| };
|
||||
105| 1| println!(
|
||||
106| 1| "Repeated, quoted string: {:?}"
|
||||
107| 1| ,
|
||||
108| 1| std::iter::repeat("repeat me")
|
||||
109| 1| .take(5)
|
||||
110| 1| .map
|
||||
111| 1| (
|
||||
112| 1| quote_closure
|
||||
113| 1| )
|
||||
114| 1| .collect::<Vec<_>>()
|
||||
115| 1| );
|
||||
116| 1|
|
||||
117| 1| let
|
||||
118| 1| _unused_closure
|
||||
119| | =
|
||||
120| | |
|
||||
121| | mut countdown
|
||||
122| | |
|
||||
123| 0| {
|
||||
124| 0| if is_false {
|
||||
125| 0| countdown = 10;
|
||||
126| 0| }
|
||||
127| 0| "closure should be unused".to_owned()
|
||||
128| 0| };
|
||||
129| |
|
||||
130| 1| let mut countdown = 10;
|
||||
131| 1| let _short_unused_closure = | _unused_arg: u8 | countdown += 1;
|
||||
LL| |#![allow(unused_assignments, unused_variables)]
|
||||
LL| |// compile-flags: -C opt-level=2
|
||||
LL| 1|fn main() { // ^^ fix described in rustc_middle/mir/mono.rs
|
||||
LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
LL| 1| // dependent conditions.
|
||||
LL| 1| let is_true = std::env::args().len() == 1;
|
||||
LL| 1| let is_false = ! is_true;
|
||||
LL| 1|
|
||||
LL| 1| let mut some_string = Some(String::from("the string content"));
|
||||
LL| 1| println!(
|
||||
LL| 1| "The string or alt: {}"
|
||||
LL| 1| ,
|
||||
LL| 1| some_string
|
||||
LL| 1| .
|
||||
LL| 1| unwrap_or_else
|
||||
LL| 1| (
|
||||
LL| 1| ||
|
||||
LL| 0| {
|
||||
LL| 0| let mut countdown = 0;
|
||||
LL| 0| if is_false {
|
||||
LL| 0| countdown = 10;
|
||||
LL| 0| }
|
||||
LL| 0| "alt string 1".to_owned()
|
||||
LL| 1| }
|
||||
LL| 1| )
|
||||
LL| 1| );
|
||||
LL| 1|
|
||||
LL| 1| some_string = Some(String::from("the string content"));
|
||||
LL| 1| let
|
||||
LL| 1| a
|
||||
LL| | =
|
||||
LL| | ||
|
||||
LL| 0| {
|
||||
LL| 0| let mut countdown = 0;
|
||||
LL| 0| if is_false {
|
||||
LL| 0| countdown = 10;
|
||||
LL| 0| }
|
||||
LL| 0| "alt string 2".to_owned()
|
||||
LL| 0| };
|
||||
LL| 1| println!(
|
||||
LL| 1| "The string or alt: {}"
|
||||
LL| 1| ,
|
||||
LL| 1| some_string
|
||||
LL| 1| .
|
||||
LL| 1| unwrap_or_else
|
||||
LL| 1| (
|
||||
LL| 1| a
|
||||
LL| 1| )
|
||||
LL| 1| );
|
||||
LL| 1|
|
||||
LL| 1| some_string = None;
|
||||
LL| 1| println!(
|
||||
LL| 1| "The string or alt: {}"
|
||||
LL| 1| ,
|
||||
LL| 1| some_string
|
||||
LL| 1| .
|
||||
LL| 1| unwrap_or_else
|
||||
LL| 1| (
|
||||
LL| 1| ||
|
||||
LL| 1| {
|
||||
LL| 1| let mut countdown = 0;
|
||||
LL| 1| if is_false {
|
||||
LL| 0| countdown = 10;
|
||||
LL| 1| }
|
||||
LL| 1| "alt string 3".to_owned()
|
||||
LL| 1| }
|
||||
LL| 1| )
|
||||
LL| 1| );
|
||||
LL| 1|
|
||||
LL| 1| some_string = None;
|
||||
LL| 1| let
|
||||
LL| 1| a
|
||||
LL| 1| =
|
||||
LL| 1| ||
|
||||
LL| 1| {
|
||||
LL| 1| let mut countdown = 0;
|
||||
LL| 1| if is_false {
|
||||
LL| 0| countdown = 10;
|
||||
LL| 1| }
|
||||
LL| 1| "alt string 4".to_owned()
|
||||
LL| 1| };
|
||||
LL| 1| println!(
|
||||
LL| 1| "The string or alt: {}"
|
||||
LL| 1| ,
|
||||
LL| 1| some_string
|
||||
LL| 1| .
|
||||
LL| 1| unwrap_or_else
|
||||
LL| 1| (
|
||||
LL| 1| a
|
||||
LL| 1| )
|
||||
LL| 1| );
|
||||
LL| 1|
|
||||
LL| 1| let
|
||||
LL| 1| quote_closure
|
||||
LL| 1| =
|
||||
LL| 1| |val|
|
||||
LL| 5| {
|
||||
LL| 5| let mut countdown = 0;
|
||||
LL| 5| if is_false {
|
||||
LL| 0| countdown = 10;
|
||||
LL| 5| }
|
||||
LL| 5| format!("'{}'", val)
|
||||
LL| 5| };
|
||||
LL| 1| println!(
|
||||
LL| 1| "Repeated, quoted string: {:?}"
|
||||
LL| 1| ,
|
||||
LL| 1| std::iter::repeat("repeat me")
|
||||
LL| 1| .take(5)
|
||||
LL| 1| .map
|
||||
LL| 1| (
|
||||
LL| 1| quote_closure
|
||||
LL| 1| )
|
||||
LL| 1| .collect::<Vec<_>>()
|
||||
LL| 1| );
|
||||
LL| 1|
|
||||
LL| 1| let
|
||||
LL| 1| _unused_closure
|
||||
LL| | =
|
||||
LL| | |
|
||||
LL| | mut countdown
|
||||
LL| | |
|
||||
LL| 0| {
|
||||
LL| 0| if is_false {
|
||||
LL| 0| countdown = 10;
|
||||
LL| 0| }
|
||||
LL| 0| "closure should be unused".to_owned()
|
||||
LL| 0| };
|
||||
LL| |
|
||||
LL| 1| let mut countdown = 10;
|
||||
LL| 1| let _short_unused_closure = | _unused_arg: u8 | countdown += 1;
|
||||
^0
|
||||
132| |
|
||||
133| |
|
||||
134| 1| let short_used_covered_closure_macro = | used_arg: u8 | println!("called");
|
||||
135| 1| let short_used_not_covered_closure_macro = | used_arg: u8 | println!("not called");
|
||||
LL| |
|
||||
LL| |
|
||||
LL| 1| let short_used_covered_closure_macro = | used_arg: u8 | println!("called");
|
||||
LL| 1| let short_used_not_covered_closure_macro = | used_arg: u8 | println!("not called");
|
||||
^0
|
||||
136| 1| let _short_unused_closure_macro = | _unused_arg: u8 | println!("not called");
|
||||
LL| 1| let _short_unused_closure_macro = | _unused_arg: u8 | println!("not called");
|
||||
^0
|
||||
137| |
|
||||
138| |
|
||||
139| |
|
||||
140| |
|
||||
141| 1| let _short_unused_closure_block = | _unused_arg: u8 | { println!("not called") };
|
||||
LL| |
|
||||
LL| |
|
||||
LL| |
|
||||
LL| |
|
||||
LL| 1| let _short_unused_closure_block = | _unused_arg: u8 | { println!("not called") };
|
||||
^0
|
||||
142| |
|
||||
143| 1| let _shortish_unused_closure = | _unused_arg: u8 | {
|
||||
144| 0| println!("not called")
|
||||
145| 0| };
|
||||
146| |
|
||||
147| 1| let _as_short_unused_closure = |
|
||||
148| | _unused_arg: u8
|
||||
149| 0| | { println!("not called") };
|
||||
150| |
|
||||
151| 1| let _almost_as_short_unused_closure = |
|
||||
152| | _unused_arg: u8
|
||||
153| 0| | { println!("not called") }
|
||||
154| | ;
|
||||
155| |
|
||||
156| |
|
||||
157| |
|
||||
158| |
|
||||
159| |
|
||||
160| 1| let _short_unused_closure_line_break_no_block = | _unused_arg: u8 |
|
||||
161| 0|println!("not called")
|
||||
162| | ;
|
||||
163| |
|
||||
164| 1| let _short_unused_closure_line_break_no_block2 =
|
||||
165| | | _unused_arg: u8 |
|
||||
166| 0| println!(
|
||||
167| 0| "not called"
|
||||
168| 0| )
|
||||
169| | ;
|
||||
170| |
|
||||
171| 1| let short_used_not_covered_closure_line_break_no_block_embedded_branch =
|
||||
172| | | _unused_arg: u8 |
|
||||
173| 0| println!(
|
||||
174| 0| "not called: {}",
|
||||
175| 0| if is_true { "check" } else { "me" }
|
||||
176| 0| )
|
||||
177| | ;
|
||||
178| |
|
||||
179| 1| let short_used_not_covered_closure_line_break_block_embedded_branch =
|
||||
180| 1| | _unused_arg: u8 |
|
||||
181| 0| {
|
||||
182| 0| println!(
|
||||
183| 0| "not called: {}",
|
||||
184| 0| if is_true { "check" } else { "me" }
|
||||
185| | )
|
||||
186| 0| }
|
||||
187| | ;
|
||||
188| |
|
||||
189| 1| let short_used_covered_closure_line_break_no_block_embedded_branch =
|
||||
190| 1| | _unused_arg: u8 |
|
||||
191| 1| println!(
|
||||
192| 1| "not called: {}",
|
||||
193| 1| if is_true { "check" } else { "me" }
|
||||
LL| |
|
||||
LL| 1| let _shortish_unused_closure = | _unused_arg: u8 | {
|
||||
LL| 0| println!("not called")
|
||||
LL| 0| };
|
||||
LL| |
|
||||
LL| 1| let _as_short_unused_closure = |
|
||||
LL| | _unused_arg: u8
|
||||
LL| 0| | { println!("not called") };
|
||||
LL| |
|
||||
LL| 1| let _almost_as_short_unused_closure = |
|
||||
LL| | _unused_arg: u8
|
||||
LL| 0| | { println!("not called") }
|
||||
LL| | ;
|
||||
LL| |
|
||||
LL| |
|
||||
LL| |
|
||||
LL| |
|
||||
LL| |
|
||||
LL| 1| let _short_unused_closure_line_break_no_block = | _unused_arg: u8 |
|
||||
LL| 0|println!("not called")
|
||||
LL| | ;
|
||||
LL| |
|
||||
LL| 1| let _short_unused_closure_line_break_no_block2 =
|
||||
LL| | | _unused_arg: u8 |
|
||||
LL| 0| println!(
|
||||
LL| 0| "not called"
|
||||
LL| 0| )
|
||||
LL| | ;
|
||||
LL| |
|
||||
LL| 1| let short_used_not_covered_closure_line_break_no_block_embedded_branch =
|
||||
LL| | | _unused_arg: u8 |
|
||||
LL| 0| println!(
|
||||
LL| 0| "not called: {}",
|
||||
LL| 0| if is_true { "check" } else { "me" }
|
||||
LL| 0| )
|
||||
LL| | ;
|
||||
LL| |
|
||||
LL| 1| let short_used_not_covered_closure_line_break_block_embedded_branch =
|
||||
LL| 1| | _unused_arg: u8 |
|
||||
LL| 0| {
|
||||
LL| 0| println!(
|
||||
LL| 0| "not called: {}",
|
||||
LL| 0| if is_true { "check" } else { "me" }
|
||||
LL| | )
|
||||
LL| 0| }
|
||||
LL| | ;
|
||||
LL| |
|
||||
LL| 1| let short_used_covered_closure_line_break_no_block_embedded_branch =
|
||||
LL| 1| | _unused_arg: u8 |
|
||||
LL| 1| println!(
|
||||
LL| 1| "not called: {}",
|
||||
LL| 1| if is_true { "check" } else { "me" }
|
||||
^0
|
||||
194| 1| )
|
||||
195| | ;
|
||||
196| |
|
||||
197| 1| let short_used_covered_closure_line_break_block_embedded_branch =
|
||||
198| 1| | _unused_arg: u8 |
|
||||
199| 1| {
|
||||
200| 1| println!(
|
||||
201| 1| "not called: {}",
|
||||
202| 1| if is_true { "check" } else { "me" }
|
||||
LL| 1| )
|
||||
LL| | ;
|
||||
LL| |
|
||||
LL| 1| let short_used_covered_closure_line_break_block_embedded_branch =
|
||||
LL| 1| | _unused_arg: u8 |
|
||||
LL| 1| {
|
||||
LL| 1| println!(
|
||||
LL| 1| "not called: {}",
|
||||
LL| 1| if is_true { "check" } else { "me" }
|
||||
^0
|
||||
203| | )
|
||||
204| 1| }
|
||||
205| | ;
|
||||
206| |
|
||||
207| 1| if is_false {
|
||||
208| 0| short_used_not_covered_closure_macro(0);
|
||||
209| 0| short_used_not_covered_closure_line_break_no_block_embedded_branch(0);
|
||||
210| 0| short_used_not_covered_closure_line_break_block_embedded_branch(0);
|
||||
211| 1| }
|
||||
212| 1| short_used_covered_closure_macro(0);
|
||||
213| 1| short_used_covered_closure_line_break_no_block_embedded_branch(0);
|
||||
214| 1| short_used_covered_closure_line_break_block_embedded_branch(0);
|
||||
215| 1|}
|
||||
LL| | )
|
||||
LL| 1| }
|
||||
LL| | ;
|
||||
LL| |
|
||||
LL| 1| if is_false {
|
||||
LL| 0| short_used_not_covered_closure_macro(0);
|
||||
LL| 0| short_used_not_covered_closure_line_break_no_block_embedded_branch(0);
|
||||
LL| 0| short_used_not_covered_closure_line_break_block_embedded_branch(0);
|
||||
LL| 1| }
|
||||
LL| 1| short_used_covered_closure_macro(0);
|
||||
LL| 1| short_used_covered_closure_line_break_no_block_embedded_branch(0);
|
||||
LL| 1| short_used_covered_closure_line_break_block_embedded_branch(0);
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,42 +1,42 @@
|
|||
1| |// compile-flags: --edition=2018
|
||||
2| |#![feature(no_coverage)]
|
||||
3| |
|
||||
4| |macro_rules! bail {
|
||||
5| | ($msg:literal $(,)?) => {
|
||||
6| | if $msg.len() > 0 {
|
||||
7| | println!("no msg");
|
||||
8| | } else {
|
||||
9| | println!($msg);
|
||||
10| | }
|
||||
11| | return Err(String::from($msg));
|
||||
12| | };
|
||||
13| |}
|
||||
14| |
|
||||
15| |macro_rules! on_error {
|
||||
16| | ($value:expr, $error_message:expr) => {
|
||||
17| | $value.or_else(|e| { // FIXME(85000): no coverage in closure macros
|
||||
18| | let message = format!($error_message, e);
|
||||
19| | if message.len() > 0 {
|
||||
20| | println!("{}", message);
|
||||
21| | Ok(String::from("ok"))
|
||||
22| | } else {
|
||||
23| | bail!("error");
|
||||
24| | }
|
||||
25| | })
|
||||
26| | };
|
||||
27| |}
|
||||
28| |
|
||||
29| 1|fn load_configuration_files() -> Result<String, String> {
|
||||
30| 1| Ok(String::from("config"))
|
||||
31| 1|}
|
||||
32| |
|
||||
33| 1|pub fn main() -> Result<(), String> {
|
||||
34| 1| println!("Starting service");
|
||||
35| 1| let config = on_error!(load_configuration_files(), "Error loading configs: {}")?;
|
||||
LL| |// compile-flags: --edition=2018
|
||||
LL| |#![feature(no_coverage)]
|
||||
LL| |
|
||||
LL| |macro_rules! bail {
|
||||
LL| | ($msg:literal $(,)?) => {
|
||||
LL| | if $msg.len() > 0 {
|
||||
LL| | println!("no msg");
|
||||
LL| | } else {
|
||||
LL| | println!($msg);
|
||||
LL| | }
|
||||
LL| | return Err(String::from($msg));
|
||||
LL| | };
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| |macro_rules! on_error {
|
||||
LL| | ($value:expr, $error_message:expr) => {
|
||||
LL| | $value.or_else(|e| { // FIXME(85000): no coverage in closure macros
|
||||
LL| | let message = format!($error_message, e);
|
||||
LL| | if message.len() > 0 {
|
||||
LL| | println!("{}", message);
|
||||
LL| | Ok(String::from("ok"))
|
||||
LL| | } else {
|
||||
LL| | bail!("error");
|
||||
LL| | }
|
||||
LL| | })
|
||||
LL| | };
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| 1|fn load_configuration_files() -> Result<String, String> {
|
||||
LL| 1| Ok(String::from("config"))
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| 1|pub fn main() -> Result<(), String> {
|
||||
LL| 1| println!("Starting service");
|
||||
LL| 1| let config = on_error!(load_configuration_files(), "Error loading configs: {}")?;
|
||||
^0
|
||||
36| |
|
||||
37| 1| let startup_delay_duration = String::from("arg");
|
||||
38| 1| let _ = (config, startup_delay_duration);
|
||||
39| 1| Ok(())
|
||||
40| 1|}
|
||||
LL| |
|
||||
LL| 1| let startup_delay_duration = String::from("arg");
|
||||
LL| 1| let _ = (config, startup_delay_duration);
|
||||
LL| 1| Ok(())
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,83 +1,83 @@
|
|||
1| |// compile-flags: --edition=2018
|
||||
2| |#![feature(no_coverage)]
|
||||
3| |
|
||||
4| |macro_rules! bail {
|
||||
5| | ($msg:literal $(,)?) => {
|
||||
6| | if $msg.len() > 0 {
|
||||
7| | println!("no msg");
|
||||
8| | } else {
|
||||
9| | println!($msg);
|
||||
10| | }
|
||||
11| | return Err(String::from($msg));
|
||||
12| | };
|
||||
13| |}
|
||||
14| |
|
||||
15| |macro_rules! on_error {
|
||||
16| | ($value:expr, $error_message:expr) => {
|
||||
17| | $value.or_else(|e| { // FIXME(85000): no coverage in closure macros
|
||||
18| | let message = format!($error_message, e);
|
||||
19| | if message.len() > 0 {
|
||||
20| | println!("{}", message);
|
||||
21| | Ok(String::from("ok"))
|
||||
22| | } else {
|
||||
23| | bail!("error");
|
||||
24| | }
|
||||
25| | })
|
||||
26| | };
|
||||
27| |}
|
||||
28| |
|
||||
29| 1|fn load_configuration_files() -> Result<String, String> {
|
||||
30| 1| Ok(String::from("config"))
|
||||
31| 1|}
|
||||
32| |
|
||||
33| 1|pub async fn test() -> Result<(), String> {
|
||||
34| 1| println!("Starting service");
|
||||
35| 1| let config = on_error!(load_configuration_files(), "Error loading configs: {}")?;
|
||||
LL| |// compile-flags: --edition=2018
|
||||
LL| |#![feature(no_coverage)]
|
||||
LL| |
|
||||
LL| |macro_rules! bail {
|
||||
LL| | ($msg:literal $(,)?) => {
|
||||
LL| | if $msg.len() > 0 {
|
||||
LL| | println!("no msg");
|
||||
LL| | } else {
|
||||
LL| | println!($msg);
|
||||
LL| | }
|
||||
LL| | return Err(String::from($msg));
|
||||
LL| | };
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| |macro_rules! on_error {
|
||||
LL| | ($value:expr, $error_message:expr) => {
|
||||
LL| | $value.or_else(|e| { // FIXME(85000): no coverage in closure macros
|
||||
LL| | let message = format!($error_message, e);
|
||||
LL| | if message.len() > 0 {
|
||||
LL| | println!("{}", message);
|
||||
LL| | Ok(String::from("ok"))
|
||||
LL| | } else {
|
||||
LL| | bail!("error");
|
||||
LL| | }
|
||||
LL| | })
|
||||
LL| | };
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| 1|fn load_configuration_files() -> Result<String, String> {
|
||||
LL| 1| Ok(String::from("config"))
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| 1|pub async fn test() -> Result<(), String> {
|
||||
LL| 1| println!("Starting service");
|
||||
LL| 1| let config = on_error!(load_configuration_files(), "Error loading configs: {}")?;
|
||||
^0
|
||||
36| |
|
||||
37| 1| let startup_delay_duration = String::from("arg");
|
||||
38| 1| let _ = (config, startup_delay_duration);
|
||||
39| 1| Ok(())
|
||||
40| 1|}
|
||||
41| |
|
||||
42| |#[no_coverage]
|
||||
43| |fn main() {
|
||||
44| | executor::block_on(test());
|
||||
45| |}
|
||||
46| |
|
||||
47| |mod executor {
|
||||
48| | use core::{
|
||||
49| | future::Future,
|
||||
50| | pin::Pin,
|
||||
51| | task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
|
||||
52| | };
|
||||
53| |
|
||||
54| | #[no_coverage]
|
||||
55| | pub fn block_on<F: Future>(mut future: F) -> F::Output {
|
||||
56| | let mut future = unsafe { Pin::new_unchecked(&mut future) };
|
||||
57| | use std::hint::unreachable_unchecked;
|
||||
58| | static VTABLE: RawWakerVTable = RawWakerVTable::new(
|
||||
59| |
|
||||
60| | #[no_coverage]
|
||||
61| | |_| unsafe { unreachable_unchecked() }, // clone
|
||||
62| |
|
||||
63| | #[no_coverage]
|
||||
64| | |_| unsafe { unreachable_unchecked() }, // wake
|
||||
65| |
|
||||
66| | #[no_coverage]
|
||||
67| | |_| unsafe { unreachable_unchecked() }, // wake_by_ref
|
||||
68| |
|
||||
69| | #[no_coverage]
|
||||
70| | |_| (),
|
||||
71| | );
|
||||
72| | let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
|
||||
73| | let mut context = Context::from_waker(&waker);
|
||||
74| |
|
||||
75| | loop {
|
||||
76| | if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
|
||||
77| | break val;
|
||||
78| | }
|
||||
79| | }
|
||||
80| | }
|
||||
81| |}
|
||||
LL| |
|
||||
LL| 1| let startup_delay_duration = String::from("arg");
|
||||
LL| 1| let _ = (config, startup_delay_duration);
|
||||
LL| 1| Ok(())
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| |#[no_coverage]
|
||||
LL| |fn main() {
|
||||
LL| | executor::block_on(test());
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| |mod executor {
|
||||
LL| | use core::{
|
||||
LL| | future::Future,
|
||||
LL| | pin::Pin,
|
||||
LL| | task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
|
||||
LL| | };
|
||||
LL| |
|
||||
LL| | #[no_coverage]
|
||||
LL| | pub fn block_on<F: Future>(mut future: F) -> F::Output {
|
||||
LL| | let mut future = unsafe { Pin::new_unchecked(&mut future) };
|
||||
LL| | use std::hint::unreachable_unchecked;
|
||||
LL| | static VTABLE: RawWakerVTable = RawWakerVTable::new(
|
||||
LL| |
|
||||
LL| | #[no_coverage]
|
||||
LL| | |_| unsafe { unreachable_unchecked() }, // clone
|
||||
LL| |
|
||||
LL| | #[no_coverage]
|
||||
LL| | |_| unsafe { unreachable_unchecked() }, // wake
|
||||
LL| |
|
||||
LL| | #[no_coverage]
|
||||
LL| | |_| unsafe { unreachable_unchecked() }, // wake_by_ref
|
||||
LL| |
|
||||
LL| | #[no_coverage]
|
||||
LL| | |_| (),
|
||||
LL| | );
|
||||
LL| | let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
|
||||
LL| | let mut context = Context::from_waker(&waker);
|
||||
LL| |
|
||||
LL| | loop {
|
||||
LL| | if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
|
||||
LL| | break val;
|
||||
LL| | }
|
||||
LL| | }
|
||||
LL| | }
|
||||
LL| |}
|
||||
|
||||
|
|
|
@ -1,94 +1,94 @@
|
|||
1| |#![allow(unused_assignments, unused_variables)]
|
||||
2| |
|
||||
3| 1|fn main() {
|
||||
4| 1| let mut countdown = 0;
|
||||
5| 1| if true {
|
||||
6| 1| countdown = 10;
|
||||
7| 1| }
|
||||
LL| |#![allow(unused_assignments, unused_variables)]
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| let mut countdown = 0;
|
||||
LL| 1| if true {
|
||||
LL| 1| countdown = 10;
|
||||
LL| 1| }
|
||||
^0
|
||||
8| |
|
||||
9| | const B: u32 = 100;
|
||||
10| 1| let x = if countdown > 7 {
|
||||
11| 1| countdown -= 4;
|
||||
12| 1| B
|
||||
13| 0| } else if countdown > 2 {
|
||||
14| 0| if countdown < 1 || countdown > 5 || countdown != 9 {
|
||||
15| 0| countdown = 0;
|
||||
16| 0| }
|
||||
17| 0| countdown -= 5;
|
||||
18| 0| countdown
|
||||
19| | } else {
|
||||
20| 0| return;
|
||||
21| | };
|
||||
22| |
|
||||
23| 1| let mut countdown = 0;
|
||||
24| 1| if true {
|
||||
25| 1| countdown = 10;
|
||||
26| 1| }
|
||||
LL| |
|
||||
LL| | const B: u32 = 100;
|
||||
LL| 1| let x = if countdown > 7 {
|
||||
LL| 1| countdown -= 4;
|
||||
LL| 1| B
|
||||
LL| 0| } else if countdown > 2 {
|
||||
LL| 0| if countdown < 1 || countdown > 5 || countdown != 9 {
|
||||
LL| 0| countdown = 0;
|
||||
LL| 0| }
|
||||
LL| 0| countdown -= 5;
|
||||
LL| 0| countdown
|
||||
LL| | } else {
|
||||
LL| 0| return;
|
||||
LL| | };
|
||||
LL| |
|
||||
LL| 1| let mut countdown = 0;
|
||||
LL| 1| if true {
|
||||
LL| 1| countdown = 10;
|
||||
LL| 1| }
|
||||
^0
|
||||
27| |
|
||||
28| 1| if countdown > 7 {
|
||||
29| 1| countdown -= 4;
|
||||
30| 1| } else if countdown > 2 {
|
||||
LL| |
|
||||
LL| 1| if countdown > 7 {
|
||||
LL| 1| countdown -= 4;
|
||||
LL| 1| } else if countdown > 2 {
|
||||
^0
|
||||
31| 0| if countdown < 1 || countdown > 5 || countdown != 9 {
|
||||
32| 0| countdown = 0;
|
||||
33| 0| }
|
||||
34| 0| countdown -= 5;
|
||||
35| | } else {
|
||||
36| 0| return;
|
||||
37| | }
|
||||
38| |
|
||||
39| 1| if true {
|
||||
40| 1| let mut countdown = 0;
|
||||
41| 1| if true {
|
||||
42| 1| countdown = 10;
|
||||
43| 1| }
|
||||
LL| 0| if countdown < 1 || countdown > 5 || countdown != 9 {
|
||||
LL| 0| countdown = 0;
|
||||
LL| 0| }
|
||||
LL| 0| countdown -= 5;
|
||||
LL| | } else {
|
||||
LL| 0| return;
|
||||
LL| | }
|
||||
LL| |
|
||||
LL| 1| if true {
|
||||
LL| 1| let mut countdown = 0;
|
||||
LL| 1| if true {
|
||||
LL| 1| countdown = 10;
|
||||
LL| 1| }
|
||||
^0
|
||||
44| |
|
||||
45| 1| if countdown > 7 {
|
||||
46| 1| countdown -= 4;
|
||||
47| 1| }
|
||||
48| 0| else if countdown > 2 {
|
||||
49| 0| if countdown < 1 || countdown > 5 || countdown != 9 {
|
||||
50| 0| countdown = 0;
|
||||
51| 0| }
|
||||
52| 0| countdown -= 5;
|
||||
53| | } else {
|
||||
54| 0| return;
|
||||
55| | }
|
||||
56| 0| }
|
||||
57| |
|
||||
58| |
|
||||
59| 1| let mut countdown = 0;
|
||||
60| 1| if true {
|
||||
61| 1| countdown = 1;
|
||||
62| 1| }
|
||||
LL| |
|
||||
LL| 1| if countdown > 7 {
|
||||
LL| 1| countdown -= 4;
|
||||
LL| 1| }
|
||||
LL| 0| else if countdown > 2 {
|
||||
LL| 0| if countdown < 1 || countdown > 5 || countdown != 9 {
|
||||
LL| 0| countdown = 0;
|
||||
LL| 0| }
|
||||
LL| 0| countdown -= 5;
|
||||
LL| | } else {
|
||||
LL| 0| return;
|
||||
LL| | }
|
||||
LL| 0| }
|
||||
LL| |
|
||||
LL| |
|
||||
LL| 1| let mut countdown = 0;
|
||||
LL| 1| if true {
|
||||
LL| 1| countdown = 1;
|
||||
LL| 1| }
|
||||
^0
|
||||
63| |
|
||||
64| 1| let z = if countdown > 7 {
|
||||
LL| |
|
||||
LL| 1| let z = if countdown > 7 {
|
||||
^0
|
||||
65| 0| countdown -= 4;
|
||||
66| 1| } else if countdown > 2 {
|
||||
67| 0| if countdown < 1 || countdown > 5 || countdown != 9 {
|
||||
68| 0| countdown = 0;
|
||||
69| 0| }
|
||||
70| 0| countdown -= 5;
|
||||
71| | } else {
|
||||
72| 1| let should_be_reachable = countdown;
|
||||
73| 1| println!("reached");
|
||||
74| 1| return;
|
||||
75| | };
|
||||
76| |
|
||||
77| 0| let w = if countdown > 7 {
|
||||
78| 0| countdown -= 4;
|
||||
79| 0| } else if countdown > 2 {
|
||||
80| 0| if countdown < 1 || countdown > 5 || countdown != 9 {
|
||||
81| 0| countdown = 0;
|
||||
82| 0| }
|
||||
83| 0| countdown -= 5;
|
||||
84| | } else {
|
||||
85| 0| return;
|
||||
86| | };
|
||||
87| 1|}
|
||||
LL| 0| countdown -= 4;
|
||||
LL| 1| } else if countdown > 2 {
|
||||
LL| 0| if countdown < 1 || countdown > 5 || countdown != 9 {
|
||||
LL| 0| countdown = 0;
|
||||
LL| 0| }
|
||||
LL| 0| countdown -= 5;
|
||||
LL| | } else {
|
||||
LL| 1| let should_be_reachable = countdown;
|
||||
LL| 1| println!("reached");
|
||||
LL| 1| return;
|
||||
LL| | };
|
||||
LL| |
|
||||
LL| 0| let w = if countdown > 7 {
|
||||
LL| 0| countdown -= 4;
|
||||
LL| 0| } else if countdown > 2 {
|
||||
LL| 0| if countdown < 1 || countdown > 5 || countdown != 9 {
|
||||
LL| 0| countdown = 0;
|
||||
LL| 0| }
|
||||
LL| 0| countdown -= 5;
|
||||
LL| | } else {
|
||||
LL| 0| return;
|
||||
LL| | };
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,70 +1,70 @@
|
|||
1| |#![allow(unused_assignments, unused_variables)]
|
||||
2| |
|
||||
3| 1|fn main() {
|
||||
4| 1| let is_true = std::env::args().len() == 1;
|
||||
5| 1|
|
||||
6| 1| let mut x = 0;
|
||||
7| 11| for _ in 0..10 {
|
||||
8| 10| match is_true {
|
||||
9| | true => {
|
||||
10| 10| continue;
|
||||
11| | }
|
||||
12| 0| _ => {
|
||||
13| 0| x = 1;
|
||||
14| 0| }
|
||||
15| 0| }
|
||||
16| 0| x = 3;
|
||||
17| | }
|
||||
18| 11| for _ in 0..10 {
|
||||
19| 10| match is_true {
|
||||
20| 0| false => {
|
||||
21| 0| x = 1;
|
||||
22| 0| }
|
||||
23| | _ => {
|
||||
24| 10| continue;
|
||||
25| | }
|
||||
26| | }
|
||||
27| 0| x = 3;
|
||||
28| | }
|
||||
29| 11| for _ in 0..10 {
|
||||
30| 10| match is_true {
|
||||
31| 10| true => {
|
||||
32| 10| x = 1;
|
||||
33| 10| }
|
||||
34| | _ => {
|
||||
35| 0| continue;
|
||||
36| | }
|
||||
37| | }
|
||||
38| 10| x = 3;
|
||||
39| | }
|
||||
40| 11| for _ in 0..10 {
|
||||
41| 10| if is_true {
|
||||
42| 10| continue;
|
||||
43| 0| }
|
||||
44| 0| x = 3;
|
||||
45| | }
|
||||
46| 11| for _ in 0..10 {
|
||||
47| 10| match is_true {
|
||||
48| 0| false => {
|
||||
49| 0| x = 1;
|
||||
50| 0| }
|
||||
51| 10| _ => {
|
||||
52| 10| let _ = x;
|
||||
53| 10| }
|
||||
54| | }
|
||||
55| 10| x = 3;
|
||||
56| | }
|
||||
57| 1| for _ in 0..10 {
|
||||
58| 1| match is_true {
|
||||
59| 0| false => {
|
||||
60| 0| x = 1;
|
||||
61| 0| }
|
||||
62| | _ => {
|
||||
63| 1| break;
|
||||
64| | }
|
||||
65| | }
|
||||
66| 0| x = 3;
|
||||
67| | }
|
||||
68| 1| let _ = x;
|
||||
69| 1|}
|
||||
LL| |#![allow(unused_assignments, unused_variables)]
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| let is_true = std::env::args().len() == 1;
|
||||
LL| 1|
|
||||
LL| 1| let mut x = 0;
|
||||
LL| 11| for _ in 0..10 {
|
||||
LL| 10| match is_true {
|
||||
LL| | true => {
|
||||
LL| 10| continue;
|
||||
LL| | }
|
||||
LL| 0| _ => {
|
||||
LL| 0| x = 1;
|
||||
LL| 0| }
|
||||
LL| 0| }
|
||||
LL| 0| x = 3;
|
||||
LL| | }
|
||||
LL| 11| for _ in 0..10 {
|
||||
LL| 10| match is_true {
|
||||
LL| 0| false => {
|
||||
LL| 0| x = 1;
|
||||
LL| 0| }
|
||||
LL| | _ => {
|
||||
LL| 10| continue;
|
||||
LL| | }
|
||||
LL| | }
|
||||
LL| 0| x = 3;
|
||||
LL| | }
|
||||
LL| 11| for _ in 0..10 {
|
||||
LL| 10| match is_true {
|
||||
LL| 10| true => {
|
||||
LL| 10| x = 1;
|
||||
LL| 10| }
|
||||
LL| | _ => {
|
||||
LL| 0| continue;
|
||||
LL| | }
|
||||
LL| | }
|
||||
LL| 10| x = 3;
|
||||
LL| | }
|
||||
LL| 11| for _ in 0..10 {
|
||||
LL| 10| if is_true {
|
||||
LL| 10| continue;
|
||||
LL| 0| }
|
||||
LL| 0| x = 3;
|
||||
LL| | }
|
||||
LL| 11| for _ in 0..10 {
|
||||
LL| 10| match is_true {
|
||||
LL| 0| false => {
|
||||
LL| 0| x = 1;
|
||||
LL| 0| }
|
||||
LL| 10| _ => {
|
||||
LL| 10| let _ = x;
|
||||
LL| 10| }
|
||||
LL| | }
|
||||
LL| 10| x = 3;
|
||||
LL| | }
|
||||
LL| 1| for _ in 0..10 {
|
||||
LL| 1| match is_true {
|
||||
LL| 0| false => {
|
||||
LL| 0| x = 1;
|
||||
LL| 0| }
|
||||
LL| | _ => {
|
||||
LL| 1| break;
|
||||
LL| | }
|
||||
LL| | }
|
||||
LL| 0| x = 3;
|
||||
LL| | }
|
||||
LL| 1| let _ = x;
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,39 +1,39 @@
|
|||
1| |#![allow(unused_assignments, unused_variables)]
|
||||
2| |
|
||||
3| 0|pub fn unused_pub_fn_not_in_library() {
|
||||
4| 0| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
5| 0| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
6| 0| // dependent conditions.
|
||||
7| 0| let is_true = std::env::args().len() == 1;
|
||||
8| 0|
|
||||
9| 0| let mut countdown = 0;
|
||||
10| 0| if is_true {
|
||||
11| 0| countdown = 10;
|
||||
12| 0| }
|
||||
13| 0|}
|
||||
14| |
|
||||
15| 0|fn unused_fn() {
|
||||
16| 0| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
17| 0| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
18| 0| // dependent conditions.
|
||||
19| 0| let is_true = std::env::args().len() == 1;
|
||||
20| 0|
|
||||
21| 0| let mut countdown = 0;
|
||||
22| 0| if is_true {
|
||||
23| 0| countdown = 10;
|
||||
24| 0| }
|
||||
25| 0|}
|
||||
26| |
|
||||
27| 1|fn main() {
|
||||
28| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
29| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
30| 1| // dependent conditions.
|
||||
31| 1| let is_true = std::env::args().len() == 1;
|
||||
32| 1|
|
||||
33| 1| let mut countdown = 0;
|
||||
34| 1| if is_true {
|
||||
35| 1| countdown = 10;
|
||||
36| 1| }
|
||||
LL| |#![allow(unused_assignments, unused_variables)]
|
||||
LL| |
|
||||
LL| 0|pub fn unused_pub_fn_not_in_library() {
|
||||
LL| 0| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
LL| 0| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
LL| 0| // dependent conditions.
|
||||
LL| 0| let is_true = std::env::args().len() == 1;
|
||||
LL| 0|
|
||||
LL| 0| let mut countdown = 0;
|
||||
LL| 0| if is_true {
|
||||
LL| 0| countdown = 10;
|
||||
LL| 0| }
|
||||
LL| 0|}
|
||||
LL| |
|
||||
LL| 0|fn unused_fn() {
|
||||
LL| 0| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
LL| 0| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
LL| 0| // dependent conditions.
|
||||
LL| 0| let is_true = std::env::args().len() == 1;
|
||||
LL| 0|
|
||||
LL| 0| let mut countdown = 0;
|
||||
LL| 0| if is_true {
|
||||
LL| 0| countdown = 10;
|
||||
LL| 0| }
|
||||
LL| 0|}
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
LL| 1| // dependent conditions.
|
||||
LL| 1| let is_true = std::env::args().len() == 1;
|
||||
LL| 1|
|
||||
LL| 1| let mut countdown = 0;
|
||||
LL| 1| if is_true {
|
||||
LL| 1| countdown = 10;
|
||||
LL| 1| }
|
||||
^0
|
||||
37| 1|}
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
1| |#![allow(unused_assignments)]
|
||||
2| |// failure-status: 1
|
||||
3| |
|
||||
4| |struct Firework {
|
||||
5| | strength: i32,
|
||||
6| |}
|
||||
7| |
|
||||
8| |impl Drop for Firework {
|
||||
9| 2| fn drop(&mut self) {
|
||||
10| 2| println!("BOOM times {}!!!", self.strength);
|
||||
11| 2| }
|
||||
12| |}
|
||||
13| |
|
||||
14| 1|fn main() -> Result<(),u8> {
|
||||
15| 1| let _firecracker = Firework { strength: 1 };
|
||||
16| 1|
|
||||
17| 1| let _tnt = Firework { strength: 100 };
|
||||
18| 1|
|
||||
19| 1| if true {
|
||||
20| 1| println!("Exiting with error...");
|
||||
21| 1| return Err(1);
|
||||
22| 0| }
|
||||
23| 0|
|
||||
24| 0| let _ = Firework { strength: 1000 };
|
||||
25| 0|
|
||||
26| 0| Ok(())
|
||||
27| 1|}
|
||||
28| |
|
||||
29| |// Expected program output:
|
||||
30| |// Exiting with error...
|
||||
31| |// BOOM times 100!!!
|
||||
32| |// BOOM times 1!!!
|
||||
33| |// Error: 1
|
||||
LL| |#![allow(unused_assignments)]
|
||||
LL| |// failure-status: 1
|
||||
LL| |
|
||||
LL| |struct Firework {
|
||||
LL| | strength: i32,
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| |impl Drop for Firework {
|
||||
LL| 2| fn drop(&mut self) {
|
||||
LL| 2| println!("BOOM times {}!!!", self.strength);
|
||||
LL| 2| }
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| 1|fn main() -> Result<(),u8> {
|
||||
LL| 1| let _firecracker = Firework { strength: 1 };
|
||||
LL| 1|
|
||||
LL| 1| let _tnt = Firework { strength: 100 };
|
||||
LL| 1|
|
||||
LL| 1| if true {
|
||||
LL| 1| println!("Exiting with error...");
|
||||
LL| 1| return Err(1);
|
||||
LL| 0| }
|
||||
LL| 0|
|
||||
LL| 0| let _ = Firework { strength: 1000 };
|
||||
LL| 0|
|
||||
LL| 0| Ok(())
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| |// Expected program output:
|
||||
LL| |// Exiting with error...
|
||||
LL| |// BOOM times 100!!!
|
||||
LL| |// BOOM times 1!!!
|
||||
LL| |// Error: 1
|
||||
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
1| |#![feature(generators, generator_trait)]
|
||||
2| |
|
||||
3| |use std::ops::{Generator, GeneratorState};
|
||||
4| |use std::pin::Pin;
|
||||
5| |
|
||||
6| |// The following implementation of a function called from a `yield` statement
|
||||
7| |// (apparently requiring the Result and the `String` type or constructor)
|
||||
8| |// creates conditions where the `generator::StateTransform` MIR transform will
|
||||
9| |// drop all `Counter` `Coverage` statements from a MIR. `simplify.rs` has logic
|
||||
10| |// to handle this condition, and still report dead block coverage.
|
||||
11| 1|fn get_u32(val: bool) -> Result<u32, String> {
|
||||
12| 1| if val { Ok(1) } else { Err(String::from("some error")) }
|
||||
LL| |#![feature(generators, generator_trait)]
|
||||
LL| |
|
||||
LL| |use std::ops::{Generator, GeneratorState};
|
||||
LL| |use std::pin::Pin;
|
||||
LL| |
|
||||
LL| |// The following implementation of a function called from a `yield` statement
|
||||
LL| |// (apparently requiring the Result and the `String` type or constructor)
|
||||
LL| |// creates conditions where the `generator::StateTransform` MIR transform will
|
||||
LL| |// drop all `Counter` `Coverage` statements from a MIR. `simplify.rs` has logic
|
||||
LL| |// to handle this condition, and still report dead block coverage.
|
||||
LL| 1|fn get_u32(val: bool) -> Result<u32, String> {
|
||||
LL| 1| if val { Ok(1) } else { Err(String::from("some error")) }
|
||||
^0
|
||||
13| 1|}
|
||||
14| |
|
||||
15| 1|fn main() {
|
||||
16| 1| let is_true = std::env::args().len() == 1;
|
||||
17| 1| let mut generator = || {
|
||||
18| 1| yield get_u32(is_true);
|
||||
19| 1| return "foo";
|
||||
20| 1| };
|
||||
21| |
|
||||
22| 1| match Pin::new(&mut generator).resume(()) {
|
||||
23| 1| GeneratorState::Yielded(Ok(1)) => {}
|
||||
24| 0| _ => panic!("unexpected return from resume"),
|
||||
25| | }
|
||||
26| 1| match Pin::new(&mut generator).resume(()) {
|
||||
27| 1| GeneratorState::Complete("foo") => {}
|
||||
28| 0| _ => panic!("unexpected return from resume"),
|
||||
29| | }
|
||||
30| 1|}
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| let is_true = std::env::args().len() == 1;
|
||||
LL| 1| let mut generator = || {
|
||||
LL| 1| yield get_u32(is_true);
|
||||
LL| 1| return "foo";
|
||||
LL| 1| };
|
||||
LL| |
|
||||
LL| 1| match Pin::new(&mut generator).resume(()) {
|
||||
LL| 1| GeneratorState::Yielded(Ok(1)) => {}
|
||||
LL| 0| _ => panic!("unexpected return from resume"),
|
||||
LL| | }
|
||||
LL| 1| match Pin::new(&mut generator).resume(()) {
|
||||
LL| 1| GeneratorState::Complete("foo") => {}
|
||||
LL| 0| _ => panic!("unexpected return from resume"),
|
||||
LL| | }
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,71 +1,71 @@
|
|||
1| |#![allow(unused_assignments)]
|
||||
2| |// failure-status: 1
|
||||
3| |
|
||||
4| |struct Firework<T> where T: Copy + std::fmt::Display {
|
||||
5| | strength: T,
|
||||
6| |}
|
||||
7| |
|
||||
8| |impl<T> Firework<T> where T: Copy + std::fmt::Display {
|
||||
9| | #[inline(always)]
|
||||
10| 3| fn set_strength(&mut self, new_strength: T) {
|
||||
11| 3| self.strength = new_strength;
|
||||
12| 3| }
|
||||
LL| |#![allow(unused_assignments)]
|
||||
LL| |// failure-status: 1
|
||||
LL| |
|
||||
LL| |struct Firework<T> where T: Copy + std::fmt::Display {
|
||||
LL| | strength: T,
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| |impl<T> Firework<T> where T: Copy + std::fmt::Display {
|
||||
LL| | #[inline(always)]
|
||||
LL| 3| fn set_strength(&mut self, new_strength: T) {
|
||||
LL| 3| self.strength = new_strength;
|
||||
LL| 3| }
|
||||
------------------
|
||||
| <generics::Firework<f64>>::set_strength:
|
||||
| 10| 2| fn set_strength(&mut self, new_strength: T) {
|
||||
| 11| 2| self.strength = new_strength;
|
||||
| 12| 2| }
|
||||
| LL| 2| fn set_strength(&mut self, new_strength: T) {
|
||||
| LL| 2| self.strength = new_strength;
|
||||
| LL| 2| }
|
||||
------------------
|
||||
| <generics::Firework<i32>>::set_strength:
|
||||
| 10| 1| fn set_strength(&mut self, new_strength: T) {
|
||||
| 11| 1| self.strength = new_strength;
|
||||
| 12| 1| }
|
||||
| LL| 1| fn set_strength(&mut self, new_strength: T) {
|
||||
| LL| 1| self.strength = new_strength;
|
||||
| LL| 1| }
|
||||
------------------
|
||||
13| |}
|
||||
14| |
|
||||
15| |impl<T> Drop for Firework<T> where T: Copy + std::fmt::Display {
|
||||
16| | #[inline(always)]
|
||||
17| 2| fn drop(&mut self) {
|
||||
18| 2| println!("BOOM times {}!!!", self.strength);
|
||||
19| 2| }
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| |impl<T> Drop for Firework<T> where T: Copy + std::fmt::Display {
|
||||
LL| | #[inline(always)]
|
||||
LL| 2| fn drop(&mut self) {
|
||||
LL| 2| println!("BOOM times {}!!!", self.strength);
|
||||
LL| 2| }
|
||||
------------------
|
||||
| <generics::Firework<f64> as core::ops::drop::Drop>::drop:
|
||||
| 17| 1| fn drop(&mut self) {
|
||||
| 18| 1| println!("BOOM times {}!!!", self.strength);
|
||||
| 19| 1| }
|
||||
| LL| 1| fn drop(&mut self) {
|
||||
| LL| 1| println!("BOOM times {}!!!", self.strength);
|
||||
| LL| 1| }
|
||||
------------------
|
||||
| <generics::Firework<i32> as core::ops::drop::Drop>::drop:
|
||||
| 17| 1| fn drop(&mut self) {
|
||||
| 18| 1| println!("BOOM times {}!!!", self.strength);
|
||||
| 19| 1| }
|
||||
| LL| 1| fn drop(&mut self) {
|
||||
| LL| 1| println!("BOOM times {}!!!", self.strength);
|
||||
| LL| 1| }
|
||||
------------------
|
||||
20| |}
|
||||
21| |
|
||||
22| 1|fn main() -> Result<(),u8> {
|
||||
23| 1| let mut firecracker = Firework { strength: 1 };
|
||||
24| 1| firecracker.set_strength(2);
|
||||
25| 1|
|
||||
26| 1| let mut tnt = Firework { strength: 100.1 };
|
||||
27| 1| tnt.set_strength(200.1);
|
||||
28| 1| tnt.set_strength(300.3);
|
||||
29| 1|
|
||||
30| 1| if true {
|
||||
31| 1| println!("Exiting with error...");
|
||||
32| 1| return Err(1);
|
||||
33| 0| }
|
||||
34| 0|
|
||||
35| 0|
|
||||
36| 0|
|
||||
37| 0|
|
||||
38| 0|
|
||||
39| 0| let _ = Firework { strength: 1000 };
|
||||
40| 0|
|
||||
41| 0| Ok(())
|
||||
42| 1|}
|
||||
43| |
|
||||
44| |// Expected program output:
|
||||
45| |// Exiting with error...
|
||||
46| |// BOOM times 100!!!
|
||||
47| |// BOOM times 1!!!
|
||||
48| |// Error: 1
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| 1|fn main() -> Result<(),u8> {
|
||||
LL| 1| let mut firecracker = Firework { strength: 1 };
|
||||
LL| 1| firecracker.set_strength(2);
|
||||
LL| 1|
|
||||
LL| 1| let mut tnt = Firework { strength: 100.1 };
|
||||
LL| 1| tnt.set_strength(200.1);
|
||||
LL| 1| tnt.set_strength(300.3);
|
||||
LL| 1|
|
||||
LL| 1| if true {
|
||||
LL| 1| println!("Exiting with error...");
|
||||
LL| 1| return Err(1);
|
||||
LL| 0| }
|
||||
LL| 0|
|
||||
LL| 0|
|
||||
LL| 0|
|
||||
LL| 0|
|
||||
LL| 0|
|
||||
LL| 0| let _ = Firework { strength: 1000 };
|
||||
LL| 0|
|
||||
LL| 0| Ok(())
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| |// Expected program output:
|
||||
LL| |// Exiting with error...
|
||||
LL| |// BOOM times 100!!!
|
||||
LL| |// BOOM times 1!!!
|
||||
LL| |// Error: 1
|
||||
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
1| |#![allow(unused_assignments, unused_variables)]
|
||||
2| |
|
||||
3| 1|fn main() {
|
||||
4| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
5| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
6| 1| // dependent conditions.
|
||||
7| 1| let
|
||||
8| 1| is_true
|
||||
9| 1| =
|
||||
10| 1| std::env::args().len()
|
||||
11| 1| ==
|
||||
12| 1| 1
|
||||
13| 1| ;
|
||||
14| 1| let
|
||||
15| 1| mut
|
||||
16| 1| countdown
|
||||
17| 1| =
|
||||
18| 1| 0
|
||||
19| 1| ;
|
||||
20| 1| if
|
||||
21| 1| is_true
|
||||
22| 1| {
|
||||
23| 1| countdown
|
||||
24| 1| =
|
||||
25| 1| 10
|
||||
26| 1| ;
|
||||
27| 1| }
|
||||
LL| |#![allow(unused_assignments, unused_variables)]
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
LL| 1| // dependent conditions.
|
||||
LL| 1| let
|
||||
LL| 1| is_true
|
||||
LL| 1| =
|
||||
LL| 1| std::env::args().len()
|
||||
LL| 1| ==
|
||||
LL| 1| 1
|
||||
LL| 1| ;
|
||||
LL| 1| let
|
||||
LL| 1| mut
|
||||
LL| 1| countdown
|
||||
LL| 1| =
|
||||
LL| 1| 0
|
||||
LL| 1| ;
|
||||
LL| 1| if
|
||||
LL| 1| is_true
|
||||
LL| 1| {
|
||||
LL| 1| countdown
|
||||
LL| 1| =
|
||||
LL| 1| 10
|
||||
LL| 1| ;
|
||||
LL| 1| }
|
||||
^0
|
||||
28| 1|}
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,41 +1,41 @@
|
|||
1| |#![allow(unused_assignments, unused_variables)]
|
||||
2| |
|
||||
3| 1|fn main() {
|
||||
4| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
5| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
6| 1| // dependent conditions.
|
||||
7| 1| let is_true = std::env::args().len() == 1;
|
||||
8| 1|
|
||||
9| 1| let mut countdown = 0;
|
||||
10| 1| if
|
||||
11| 1| is_true
|
||||
12| 1| {
|
||||
13| 1| countdown
|
||||
14| 1| =
|
||||
15| 1| 10
|
||||
16| 1| ;
|
||||
17| 1| }
|
||||
18| | else // Note coverage region difference without semicolon
|
||||
19| | {
|
||||
20| 0| countdown
|
||||
21| 0| =
|
||||
22| 0| 100
|
||||
23| | }
|
||||
24| |
|
||||
25| | if
|
||||
26| 1| is_true
|
||||
27| 1| {
|
||||
28| 1| countdown
|
||||
29| 1| =
|
||||
30| 1| 10
|
||||
31| 1| ;
|
||||
32| 1| }
|
||||
33| | else
|
||||
34| 0| {
|
||||
35| 0| countdown
|
||||
36| 0| =
|
||||
37| 0| 100
|
||||
38| 0| ;
|
||||
39| 0| }
|
||||
40| 1|}
|
||||
LL| |#![allow(unused_assignments, unused_variables)]
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
LL| 1| // dependent conditions.
|
||||
LL| 1| let is_true = std::env::args().len() == 1;
|
||||
LL| 1|
|
||||
LL| 1| let mut countdown = 0;
|
||||
LL| 1| if
|
||||
LL| 1| is_true
|
||||
LL| 1| {
|
||||
LL| 1| countdown
|
||||
LL| 1| =
|
||||
LL| 1| 10
|
||||
LL| 1| ;
|
||||
LL| 1| }
|
||||
LL| | else // Note coverage region difference without semicolon
|
||||
LL| | {
|
||||
LL| 0| countdown
|
||||
LL| 0| =
|
||||
LL| 0| 100
|
||||
LL| | }
|
||||
LL| |
|
||||
LL| | if
|
||||
LL| 1| is_true
|
||||
LL| 1| {
|
||||
LL| 1| countdown
|
||||
LL| 1| =
|
||||
LL| 1| 10
|
||||
LL| 1| ;
|
||||
LL| 1| }
|
||||
LL| | else
|
||||
LL| 0| {
|
||||
LL| 0| countdown
|
||||
LL| 0| =
|
||||
LL| 0| 100
|
||||
LL| 0| ;
|
||||
LL| 0| }
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
1| |// Regression test for issue #98833.
|
||||
2| |// compile-flags: -Zinline-mir -Cdebug-assertions=off
|
||||
3| |
|
||||
4| 1|fn main() {
|
||||
5| 1| println!("{}", live::<false>());
|
||||
6| 1|
|
||||
7| 1| let f = |x: bool| {
|
||||
8| | debug_assert!(
|
||||
9| 0| x
|
||||
10| | );
|
||||
11| 1| };
|
||||
12| 1| f(false);
|
||||
13| 1|}
|
||||
14| |
|
||||
15| |#[inline]
|
||||
16| 1|fn live<const B: bool>() -> u32 {
|
||||
17| 1| if B {
|
||||
18| 0| dead()
|
||||
19| | } else {
|
||||
20| 1| 0
|
||||
21| | }
|
||||
22| 1|}
|
||||
23| |
|
||||
24| |#[inline]
|
||||
25| 0|fn dead() -> u32 {
|
||||
26| 0| 42
|
||||
27| 0|}
|
||||
LL| |// Regression test for issue #98833.
|
||||
LL| |// compile-flags: -Zinline-mir -Cdebug-assertions=off
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| println!("{}", live::<false>());
|
||||
LL| 1|
|
||||
LL| 1| let f = |x: bool| {
|
||||
LL| | debug_assert!(
|
||||
LL| 0| x
|
||||
LL| | );
|
||||
LL| 1| };
|
||||
LL| 1| f(false);
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| |#[inline]
|
||||
LL| 1|fn live<const B: bool>() -> u32 {
|
||||
LL| 1| if B {
|
||||
LL| 0| dead()
|
||||
LL| | } else {
|
||||
LL| 1| 0
|
||||
LL| | }
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| |#[inline]
|
||||
LL| 0|fn dead() -> u32 {
|
||||
LL| 0| 42
|
||||
LL| 0|}
|
||||
|
||||
|
|
|
@ -1,54 +1,54 @@
|
|||
1| |// compile-flags: -Zinline-mir
|
||||
2| |
|
||||
3| |use std::fmt::Display;
|
||||
4| |
|
||||
5| 1|fn main() {
|
||||
6| 1| permutations(&['a', 'b', 'c']);
|
||||
7| 1|}
|
||||
8| |
|
||||
9| |#[inline(always)]
|
||||
10| 1|fn permutations<T: Copy + Display>(xs: &[T]) {
|
||||
11| 1| let mut ys = xs.to_owned();
|
||||
12| 1| permutate(&mut ys, 0);
|
||||
13| 1|}
|
||||
14| |
|
||||
15| 16|fn permutate<T: Copy + Display>(xs: &mut [T], k: usize) {
|
||||
16| 16| let n = length(xs);
|
||||
17| 16| if k == n {
|
||||
18| 6| display(xs);
|
||||
19| 10| } else if k < n {
|
||||
20| 15| for i in k..n {
|
||||
LL| |// compile-flags: -Zinline-mir
|
||||
LL| |
|
||||
LL| |use std::fmt::Display;
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| permutations(&['a', 'b', 'c']);
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| |#[inline(always)]
|
||||
LL| 1|fn permutations<T: Copy + Display>(xs: &[T]) {
|
||||
LL| 1| let mut ys = xs.to_owned();
|
||||
LL| 1| permutate(&mut ys, 0);
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| 16|fn permutate<T: Copy + Display>(xs: &mut [T], k: usize) {
|
||||
LL| 16| let n = length(xs);
|
||||
LL| 16| if k == n {
|
||||
LL| 6| display(xs);
|
||||
LL| 10| } else if k < n {
|
||||
LL| 15| for i in k..n {
|
||||
^10
|
||||
21| 15| swap(xs, i, k);
|
||||
22| 15| permutate(xs, k + 1);
|
||||
23| 15| swap(xs, i, k);
|
||||
24| 15| }
|
||||
25| 0| } else {
|
||||
26| 0| error();
|
||||
27| 0| }
|
||||
28| 16|}
|
||||
29| |
|
||||
30| 16|fn length<T>(xs: &[T]) -> usize {
|
||||
31| 16| xs.len()
|
||||
32| 16|}
|
||||
33| |
|
||||
34| |#[inline]
|
||||
35| 30|fn swap<T: Copy>(xs: &mut [T], i: usize, j: usize) {
|
||||
36| 30| let t = xs[i];
|
||||
37| 30| xs[i] = xs[j];
|
||||
38| 30| xs[j] = t;
|
||||
39| 30|}
|
||||
40| |
|
||||
41| 6|fn display<T: Display>(xs: &[T]) {
|
||||
42| 24| for x in xs {
|
||||
LL| 15| swap(xs, i, k);
|
||||
LL| 15| permutate(xs, k + 1);
|
||||
LL| 15| swap(xs, i, k);
|
||||
LL| 15| }
|
||||
LL| 0| } else {
|
||||
LL| 0| error();
|
||||
LL| 0| }
|
||||
LL| 16|}
|
||||
LL| |
|
||||
LL| 16|fn length<T>(xs: &[T]) -> usize {
|
||||
LL| 16| xs.len()
|
||||
LL| 16|}
|
||||
LL| |
|
||||
LL| |#[inline]
|
||||
LL| 30|fn swap<T: Copy>(xs: &mut [T], i: usize, j: usize) {
|
||||
LL| 30| let t = xs[i];
|
||||
LL| 30| xs[i] = xs[j];
|
||||
LL| 30| xs[j] = t;
|
||||
LL| 30|}
|
||||
LL| |
|
||||
LL| 6|fn display<T: Display>(xs: &[T]) {
|
||||
LL| 24| for x in xs {
|
||||
^18
|
||||
43| 18| print!("{}", x);
|
||||
44| 18| }
|
||||
45| 6| println!();
|
||||
46| 6|}
|
||||
47| |
|
||||
48| |#[inline(always)]
|
||||
49| 0|fn error() {
|
||||
50| 0| panic!("error");
|
||||
51| 0|}
|
||||
LL| 18| print!("{}", x);
|
||||
LL| 18| }
|
||||
LL| 6| println!();
|
||||
LL| 6|}
|
||||
LL| |
|
||||
LL| |#[inline(always)]
|
||||
LL| 0|fn error() {
|
||||
LL| 0| panic!("error");
|
||||
LL| 0|}
|
||||
|
||||
|
|
|
@ -1,60 +1,60 @@
|
|||
1| |#![allow(unused_assignments, unused_variables, dead_code)]
|
||||
2| |
|
||||
3| 1|fn main() {
|
||||
4| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
5| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
6| 1| // dependent conditions.
|
||||
7| 1| let is_true = std::env::args().len() == 1;
|
||||
8| 1|
|
||||
9| 1| let mut countdown = 0;
|
||||
10| 1| if is_true {
|
||||
11| 1| countdown = 10;
|
||||
12| 1| }
|
||||
LL| |#![allow(unused_assignments, unused_variables, dead_code)]
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
LL| 1| // dependent conditions.
|
||||
LL| 1| let is_true = std::env::args().len() == 1;
|
||||
LL| 1|
|
||||
LL| 1| let mut countdown = 0;
|
||||
LL| 1| if is_true {
|
||||
LL| 1| countdown = 10;
|
||||
LL| 1| }
|
||||
^0
|
||||
13| |
|
||||
14| | mod in_mod {
|
||||
15| | const IN_MOD_CONST: u32 = 1000;
|
||||
16| | }
|
||||
17| |
|
||||
18| 3| fn in_func(a: u32) {
|
||||
19| 3| let b = 1;
|
||||
20| 3| let c = a + b;
|
||||
21| 3| println!("c = {}", c)
|
||||
22| 3| }
|
||||
23| |
|
||||
24| | struct InStruct {
|
||||
25| | in_struct_field: u32,
|
||||
26| | }
|
||||
27| |
|
||||
28| | const IN_CONST: u32 = 1234;
|
||||
29| |
|
||||
30| | trait InTrait {
|
||||
31| | fn trait_func(&mut self, incr: u32);
|
||||
32| |
|
||||
33| 1| fn default_trait_func(&mut self) {
|
||||
34| 1| in_func(IN_CONST);
|
||||
35| 1| self.trait_func(IN_CONST);
|
||||
36| 1| }
|
||||
37| | }
|
||||
38| |
|
||||
39| | impl InTrait for InStruct {
|
||||
40| 1| fn trait_func(&mut self, incr: u32) {
|
||||
41| 1| self.in_struct_field += incr;
|
||||
42| 1| in_func(self.in_struct_field);
|
||||
43| 1| }
|
||||
44| | }
|
||||
45| |
|
||||
46| | type InType = String;
|
||||
47| |
|
||||
48| 1| if is_true {
|
||||
49| 1| in_func(countdown);
|
||||
50| 1| }
|
||||
LL| |
|
||||
LL| | mod in_mod {
|
||||
LL| | const IN_MOD_CONST: u32 = 1000;
|
||||
LL| | }
|
||||
LL| |
|
||||
LL| 3| fn in_func(a: u32) {
|
||||
LL| 3| let b = 1;
|
||||
LL| 3| let c = a + b;
|
||||
LL| 3| println!("c = {}", c)
|
||||
LL| 3| }
|
||||
LL| |
|
||||
LL| | struct InStruct {
|
||||
LL| | in_struct_field: u32,
|
||||
LL| | }
|
||||
LL| |
|
||||
LL| | const IN_CONST: u32 = 1234;
|
||||
LL| |
|
||||
LL| | trait InTrait {
|
||||
LL| | fn trait_func(&mut self, incr: u32);
|
||||
LL| |
|
||||
LL| 1| fn default_trait_func(&mut self) {
|
||||
LL| 1| in_func(IN_CONST);
|
||||
LL| 1| self.trait_func(IN_CONST);
|
||||
LL| 1| }
|
||||
LL| | }
|
||||
LL| |
|
||||
LL| | impl InTrait for InStruct {
|
||||
LL| 1| fn trait_func(&mut self, incr: u32) {
|
||||
LL| 1| self.in_struct_field += incr;
|
||||
LL| 1| in_func(self.in_struct_field);
|
||||
LL| 1| }
|
||||
LL| | }
|
||||
LL| |
|
||||
LL| | type InType = String;
|
||||
LL| |
|
||||
LL| 1| if is_true {
|
||||
LL| 1| in_func(countdown);
|
||||
LL| 1| }
|
||||
^0
|
||||
51| |
|
||||
52| 1| let mut val = InStruct {
|
||||
53| 1| in_struct_field: 101,
|
||||
54| 1| };
|
||||
55| 1|
|
||||
56| 1| val.default_trait_func();
|
||||
57| 1|}
|
||||
LL| |
|
||||
LL| 1| let mut val = InStruct {
|
||||
LL| 1| in_struct_field: 101,
|
||||
LL| 1| };
|
||||
LL| 1|
|
||||
LL| 1| val.default_trait_func();
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
1| |// Shows that rust-lang/rust/83601 is resolved
|
||||
2| |
|
||||
3| 3|#[derive(Debug, PartialEq, Eq)]
|
||||
LL| |// Shows that rust-lang/rust/83601 is resolved
|
||||
LL| |
|
||||
LL| 3|#[derive(Debug, PartialEq, Eq)]
|
||||
^2
|
||||
4| |struct Foo(u32);
|
||||
5| |
|
||||
6| 1|fn main() {
|
||||
7| 1| let bar = Foo(1);
|
||||
8| 1| assert_eq!(bar, Foo(1));
|
||||
9| 1| let baz = Foo(0);
|
||||
10| 1| assert_ne!(baz, Foo(1));
|
||||
11| 1| println!("{:?}", Foo(1));
|
||||
12| 1| println!("{:?}", bar);
|
||||
13| 1| println!("{:?}", baz);
|
||||
14| 1|}
|
||||
LL| |struct Foo(u32);
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| let bar = Foo(1);
|
||||
LL| 1| assert_eq!(bar, Foo(1));
|
||||
LL| 1| let baz = Foo(0);
|
||||
LL| 1| assert_ne!(baz, Foo(1));
|
||||
LL| 1| println!("{:?}", Foo(1));
|
||||
LL| 1| println!("{:?}", bar);
|
||||
LL| 1| println!("{:?}", baz);
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,189 +1,189 @@
|
|||
1| |// This demonstrated Issue #84561: function-like macros produce unintuitive coverage results.
|
||||
2| |
|
||||
3| |// failure-status: 101
|
||||
4| 21|#[derive(PartialEq, Eq)]
|
||||
5| |struct Foo(u32);
|
||||
6| 1|fn test3() {
|
||||
7| 1| let is_true = std::env::args().len() == 1;
|
||||
8| 1| let bar = Foo(1);
|
||||
9| 1| assert_eq!(bar, Foo(1));
|
||||
10| 1| let baz = Foo(0);
|
||||
11| 1| assert_ne!(baz, Foo(1));
|
||||
12| 1| println!("{:?}", Foo(1));
|
||||
13| 1| println!("{:?}", bar);
|
||||
14| 1| println!("{:?}", baz);
|
||||
15| 1|
|
||||
16| 1| assert_eq!(Foo(1), Foo(1));
|
||||
17| 1| assert_ne!(Foo(0), Foo(1));
|
||||
18| 1| assert_eq!(Foo(2), Foo(2));
|
||||
19| 1| let bar = Foo(0);
|
||||
20| 1| assert_ne!(bar, Foo(3));
|
||||
21| 1| assert_ne!(Foo(0), Foo(4));
|
||||
22| 1| assert_eq!(Foo(3), Foo(3), "with a message");
|
||||
LL| |// This demonstrated Issue #84561: function-like macros produce unintuitive coverage results.
|
||||
LL| |
|
||||
LL| |// failure-status: 101
|
||||
LL| 21|#[derive(PartialEq, Eq)]
|
||||
LL| |struct Foo(u32);
|
||||
LL| 1|fn test3() {
|
||||
LL| 1| let is_true = std::env::args().len() == 1;
|
||||
LL| 1| let bar = Foo(1);
|
||||
LL| 1| assert_eq!(bar, Foo(1));
|
||||
LL| 1| let baz = Foo(0);
|
||||
LL| 1| assert_ne!(baz, Foo(1));
|
||||
LL| 1| println!("{:?}", Foo(1));
|
||||
LL| 1| println!("{:?}", bar);
|
||||
LL| 1| println!("{:?}", baz);
|
||||
LL| 1|
|
||||
LL| 1| assert_eq!(Foo(1), Foo(1));
|
||||
LL| 1| assert_ne!(Foo(0), Foo(1));
|
||||
LL| 1| assert_eq!(Foo(2), Foo(2));
|
||||
LL| 1| let bar = Foo(0);
|
||||
LL| 1| assert_ne!(bar, Foo(3));
|
||||
LL| 1| assert_ne!(Foo(0), Foo(4));
|
||||
LL| 1| assert_eq!(Foo(3), Foo(3), "with a message");
|
||||
^0
|
||||
23| 1| println!("{:?}", bar);
|
||||
24| 1| println!("{:?}", Foo(1));
|
||||
25| 1|
|
||||
26| 1| assert_ne!(Foo(0), Foo(5), "{}", if is_true { "true message" } else { "false message" });
|
||||
LL| 1| println!("{:?}", bar);
|
||||
LL| 1| println!("{:?}", Foo(1));
|
||||
LL| 1|
|
||||
LL| 1| assert_ne!(Foo(0), Foo(5), "{}", if is_true { "true message" } else { "false message" });
|
||||
^0 ^0 ^0
|
||||
27| 1| assert_ne!(
|
||||
28| | Foo(0)
|
||||
29| | ,
|
||||
30| | Foo(5)
|
||||
31| | ,
|
||||
32| 0| "{}"
|
||||
33| 0| ,
|
||||
34| 0| if
|
||||
35| 0| is_true
|
||||
36| | {
|
||||
37| 0| "true message"
|
||||
38| | } else {
|
||||
39| 0| "false message"
|
||||
40| | }
|
||||
41| | );
|
||||
42| |
|
||||
43| 1| let is_true = std::env::args().len() == 1;
|
||||
44| 1|
|
||||
45| 1| assert_eq!(
|
||||
46| 1| Foo(1),
|
||||
47| 1| Foo(1)
|
||||
48| 1| );
|
||||
49| 1| assert_ne!(
|
||||
50| 1| Foo(0),
|
||||
51| 1| Foo(1)
|
||||
52| 1| );
|
||||
53| 1| assert_eq!(
|
||||
54| 1| Foo(2),
|
||||
55| 1| Foo(2)
|
||||
56| 1| );
|
||||
57| 1| let bar = Foo(1);
|
||||
58| 1| assert_ne!(
|
||||
59| 1| bar,
|
||||
60| 1| Foo(3)
|
||||
61| 1| );
|
||||
62| 1| if is_true {
|
||||
63| 1| assert_ne!(
|
||||
64| 1| Foo(0),
|
||||
65| 1| Foo(4)
|
||||
66| 1| );
|
||||
67| | } else {
|
||||
68| 0| assert_eq!(
|
||||
69| 0| Foo(3),
|
||||
70| 0| Foo(3)
|
||||
71| 0| );
|
||||
72| | }
|
||||
73| 1| if is_true {
|
||||
74| 1| assert_ne!(
|
||||
75| | Foo(0),
|
||||
76| | Foo(4),
|
||||
77| 0| "with a message"
|
||||
78| | );
|
||||
79| | } else {
|
||||
80| 0| assert_eq!(
|
||||
81| | Foo(3),
|
||||
82| | Foo(3),
|
||||
83| 0| "with a message"
|
||||
84| | );
|
||||
85| | }
|
||||
86| 1| assert_ne!(
|
||||
87| 1| if is_true {
|
||||
88| 1| Foo(0)
|
||||
89| | } else {
|
||||
90| 0| Foo(1)
|
||||
91| | },
|
||||
92| | Foo(5)
|
||||
93| | );
|
||||
94| 1| assert_ne!(
|
||||
95| 1| Foo(5),
|
||||
96| 1| if is_true {
|
||||
97| 1| Foo(0)
|
||||
98| | } else {
|
||||
99| 0| Foo(1)
|
||||
100| | }
|
||||
101| | );
|
||||
102| 1| assert_ne!(
|
||||
103| 1| if is_true {
|
||||
104| 1| assert_eq!(
|
||||
105| 1| Foo(3),
|
||||
106| 1| Foo(3)
|
||||
107| 1| );
|
||||
108| 1| Foo(0)
|
||||
109| | } else {
|
||||
110| 0| assert_ne!(
|
||||
111| 0| if is_true {
|
||||
112| 0| Foo(0)
|
||||
113| | } else {
|
||||
114| 0| Foo(1)
|
||||
115| | },
|
||||
116| | Foo(5)
|
||||
117| | );
|
||||
118| 0| Foo(1)
|
||||
119| | },
|
||||
120| | Foo(5),
|
||||
121| 0| "with a message"
|
||||
122| | );
|
||||
123| 1| assert_eq!(
|
||||
124| | Foo(1),
|
||||
125| | Foo(3),
|
||||
126| 1| "this assert should fail"
|
||||
127| | );
|
||||
128| 0| assert_eq!(
|
||||
129| | Foo(3),
|
||||
130| | Foo(3),
|
||||
131| 0| "this assert should not be reached"
|
||||
132| | );
|
||||
133| 0|}
|
||||
134| |
|
||||
135| |impl std::fmt::Debug for Foo {
|
||||
136| | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
137| 7| write!(f, "try and succeed")?;
|
||||
LL| 1| assert_ne!(
|
||||
LL| | Foo(0)
|
||||
LL| | ,
|
||||
LL| | Foo(5)
|
||||
LL| | ,
|
||||
LL| 0| "{}"
|
||||
LL| 0| ,
|
||||
LL| 0| if
|
||||
LL| 0| is_true
|
||||
LL| | {
|
||||
LL| 0| "true message"
|
||||
LL| | } else {
|
||||
LL| 0| "false message"
|
||||
LL| | }
|
||||
LL| | );
|
||||
LL| |
|
||||
LL| 1| let is_true = std::env::args().len() == 1;
|
||||
LL| 1|
|
||||
LL| 1| assert_eq!(
|
||||
LL| 1| Foo(1),
|
||||
LL| 1| Foo(1)
|
||||
LL| 1| );
|
||||
LL| 1| assert_ne!(
|
||||
LL| 1| Foo(0),
|
||||
LL| 1| Foo(1)
|
||||
LL| 1| );
|
||||
LL| 1| assert_eq!(
|
||||
LL| 1| Foo(2),
|
||||
LL| 1| Foo(2)
|
||||
LL| 1| );
|
||||
LL| 1| let bar = Foo(1);
|
||||
LL| 1| assert_ne!(
|
||||
LL| 1| bar,
|
||||
LL| 1| Foo(3)
|
||||
LL| 1| );
|
||||
LL| 1| if is_true {
|
||||
LL| 1| assert_ne!(
|
||||
LL| 1| Foo(0),
|
||||
LL| 1| Foo(4)
|
||||
LL| 1| );
|
||||
LL| | } else {
|
||||
LL| 0| assert_eq!(
|
||||
LL| 0| Foo(3),
|
||||
LL| 0| Foo(3)
|
||||
LL| 0| );
|
||||
LL| | }
|
||||
LL| 1| if is_true {
|
||||
LL| 1| assert_ne!(
|
||||
LL| | Foo(0),
|
||||
LL| | Foo(4),
|
||||
LL| 0| "with a message"
|
||||
LL| | );
|
||||
LL| | } else {
|
||||
LL| 0| assert_eq!(
|
||||
LL| | Foo(3),
|
||||
LL| | Foo(3),
|
||||
LL| 0| "with a message"
|
||||
LL| | );
|
||||
LL| | }
|
||||
LL| 1| assert_ne!(
|
||||
LL| 1| if is_true {
|
||||
LL| 1| Foo(0)
|
||||
LL| | } else {
|
||||
LL| 0| Foo(1)
|
||||
LL| | },
|
||||
LL| | Foo(5)
|
||||
LL| | );
|
||||
LL| 1| assert_ne!(
|
||||
LL| 1| Foo(5),
|
||||
LL| 1| if is_true {
|
||||
LL| 1| Foo(0)
|
||||
LL| | } else {
|
||||
LL| 0| Foo(1)
|
||||
LL| | }
|
||||
LL| | );
|
||||
LL| 1| assert_ne!(
|
||||
LL| 1| if is_true {
|
||||
LL| 1| assert_eq!(
|
||||
LL| 1| Foo(3),
|
||||
LL| 1| Foo(3)
|
||||
LL| 1| );
|
||||
LL| 1| Foo(0)
|
||||
LL| | } else {
|
||||
LL| 0| assert_ne!(
|
||||
LL| 0| if is_true {
|
||||
LL| 0| Foo(0)
|
||||
LL| | } else {
|
||||
LL| 0| Foo(1)
|
||||
LL| | },
|
||||
LL| | Foo(5)
|
||||
LL| | );
|
||||
LL| 0| Foo(1)
|
||||
LL| | },
|
||||
LL| | Foo(5),
|
||||
LL| 0| "with a message"
|
||||
LL| | );
|
||||
LL| 1| assert_eq!(
|
||||
LL| | Foo(1),
|
||||
LL| | Foo(3),
|
||||
LL| 1| "this assert should fail"
|
||||
LL| | );
|
||||
LL| 0| assert_eq!(
|
||||
LL| | Foo(3),
|
||||
LL| | Foo(3),
|
||||
LL| 0| "this assert should not be reached"
|
||||
LL| | );
|
||||
LL| 0|}
|
||||
LL| |
|
||||
LL| |impl std::fmt::Debug for Foo {
|
||||
LL| | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
LL| 7| write!(f, "try and succeed")?;
|
||||
^0
|
||||
138| 7| Ok(())
|
||||
139| 7| }
|
||||
140| |}
|
||||
141| |
|
||||
142| |static mut DEBUG_LEVEL_ENABLED: bool = false;
|
||||
143| |
|
||||
144| |macro_rules! debug {
|
||||
145| | ($($arg:tt)+) => (
|
||||
146| | if unsafe { DEBUG_LEVEL_ENABLED } {
|
||||
147| | println!($($arg)+);
|
||||
148| | }
|
||||
149| | );
|
||||
150| |}
|
||||
151| |
|
||||
152| 1|fn test1() {
|
||||
153| 1| debug!("debug is enabled");
|
||||
LL| 7| Ok(())
|
||||
LL| 7| }
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| |static mut DEBUG_LEVEL_ENABLED: bool = false;
|
||||
LL| |
|
||||
LL| |macro_rules! debug {
|
||||
LL| | ($($arg:tt)+) => (
|
||||
LL| | if unsafe { DEBUG_LEVEL_ENABLED } {
|
||||
LL| | println!($($arg)+);
|
||||
LL| | }
|
||||
LL| | );
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| 1|fn test1() {
|
||||
LL| 1| debug!("debug is enabled");
|
||||
^0
|
||||
154| 1| debug!("debug is enabled");
|
||||
LL| 1| debug!("debug is enabled");
|
||||
^0
|
||||
155| 1| let _ = 0;
|
||||
156| 1| debug!("debug is enabled");
|
||||
LL| 1| let _ = 0;
|
||||
LL| 1| debug!("debug is enabled");
|
||||
^0
|
||||
157| 1| unsafe {
|
||||
158| 1| DEBUG_LEVEL_ENABLED = true;
|
||||
159| 1| }
|
||||
160| 1| debug!("debug is enabled");
|
||||
161| 1|}
|
||||
162| |
|
||||
163| |macro_rules! call_debug {
|
||||
164| | ($($arg:tt)+) => (
|
||||
165| 1| fn call_print(s: &str) {
|
||||
166| 1| print!("{}", s);
|
||||
167| 1| }
|
||||
168| |
|
||||
169| | call_print("called from call_debug: ");
|
||||
170| | debug!($($arg)+);
|
||||
171| | );
|
||||
172| |}
|
||||
173| |
|
||||
174| 1|fn test2() {
|
||||
175| 1| call_debug!("debug is enabled");
|
||||
176| 1|}
|
||||
177| |
|
||||
178| 1|fn main() {
|
||||
179| 1| test1();
|
||||
180| 1| test2();
|
||||
181| 1| test3();
|
||||
182| 1|}
|
||||
LL| 1| unsafe {
|
||||
LL| 1| DEBUG_LEVEL_ENABLED = true;
|
||||
LL| 1| }
|
||||
LL| 1| debug!("debug is enabled");
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| |macro_rules! call_debug {
|
||||
LL| | ($($arg:tt)+) => (
|
||||
LL| 1| fn call_print(s: &str) {
|
||||
LL| 1| print!("{}", s);
|
||||
LL| 1| }
|
||||
LL| |
|
||||
LL| | call_print("called from call_debug: ");
|
||||
LL| | debug!($($arg)+);
|
||||
LL| | );
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| 1|fn test2() {
|
||||
LL| 1| call_debug!("debug is enabled");
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| test1();
|
||||
LL| 1| test2();
|
||||
LL| 1| test3();
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,36 +1,36 @@
|
|||
$DIR/auxiliary/inline_always_with_dead_code.rs:
|
||||
1| |// compile-flags: -Cinstrument-coverage -Ccodegen-units=4 -Copt-level=0
|
||||
2| |
|
||||
3| |#![allow(dead_code)]
|
||||
4| |
|
||||
5| |mod foo {
|
||||
6| | #[inline(always)]
|
||||
7| 2| pub fn called() { }
|
||||
8| |
|
||||
9| 0| fn uncalled() { }
|
||||
10| |}
|
||||
11| |
|
||||
12| |pub mod bar {
|
||||
13| 1| pub fn call_me() {
|
||||
14| 1| super::foo::called();
|
||||
15| 1| }
|
||||
16| |}
|
||||
17| |
|
||||
18| |pub mod baz {
|
||||
19| 1| pub fn call_me() {
|
||||
20| 1| super::foo::called();
|
||||
21| 1| }
|
||||
22| |}
|
||||
LL| |// compile-flags: -Cinstrument-coverage -Ccodegen-units=4 -Copt-level=0
|
||||
LL| |
|
||||
LL| |#![allow(dead_code)]
|
||||
LL| |
|
||||
LL| |mod foo {
|
||||
LL| | #[inline(always)]
|
||||
LL| 2| pub fn called() { }
|
||||
LL| |
|
||||
LL| 0| fn uncalled() { }
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| |pub mod bar {
|
||||
LL| 1| pub fn call_me() {
|
||||
LL| 1| super::foo::called();
|
||||
LL| 1| }
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| |pub mod baz {
|
||||
LL| 1| pub fn call_me() {
|
||||
LL| 1| super::foo::called();
|
||||
LL| 1| }
|
||||
LL| |}
|
||||
|
||||
$DIR/issue-85461.rs:
|
||||
1| |// Regression test for #85461: MSVC sometimes fail to link with dead code and #[inline(always)]
|
||||
2| |// aux-build:inline_always_with_dead_code.rs
|
||||
3| |extern crate inline_always_with_dead_code;
|
||||
4| |
|
||||
5| |use inline_always_with_dead_code::{bar, baz};
|
||||
6| |
|
||||
7| 1|fn main() {
|
||||
8| 1| bar::call_me();
|
||||
9| 1| baz::call_me();
|
||||
10| 1|}
|
||||
LL| |// Regression test for #85461: MSVC sometimes fail to link with dead code and #[inline(always)]
|
||||
LL| |// aux-build:inline_always_with_dead_code.rs
|
||||
LL| |extern crate inline_always_with_dead_code;
|
||||
LL| |
|
||||
LL| |use inline_always_with_dead_code::{bar, baz};
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| bar::call_me();
|
||||
LL| 1| baz::call_me();
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
1| |// Regression test for #93054: Functions using uninhabited types often only have a single,
|
||||
2| |// unreachable basic block which doesn't get instrumented. This should not cause llvm-cov to fail.
|
||||
3| |// Since these kinds functions can't be invoked anyway, it's ok to not have coverage data for them.
|
||||
4| |
|
||||
5| |// compile-flags: --edition=2021
|
||||
6| |
|
||||
7| |enum Never { }
|
||||
8| |
|
||||
9| |impl Never {
|
||||
10| | fn foo(self) {
|
||||
11| | match self { }
|
||||
12| | make().map(|never| match never { });
|
||||
13| | }
|
||||
14| |
|
||||
15| | fn bar(&self) {
|
||||
16| | match *self { }
|
||||
17| | }
|
||||
18| |}
|
||||
19| |
|
||||
20| 0|async fn foo2(never: Never) {
|
||||
21| | match never { }
|
||||
22| |}
|
||||
23| |
|
||||
24| 0|fn make() -> Option<Never> {
|
||||
25| 0| None
|
||||
26| 0|}
|
||||
27| |
|
||||
28| 1|fn main() { }
|
||||
LL| |// Regression test for #93054: Functions using uninhabited types often only have a single,
|
||||
LL| |// unreachable basic block which doesn't get instrumented. This should not cause llvm-cov to fail.
|
||||
LL| |// Since these kinds functions can't be invoked anyway, it's ok to not have coverage data for them.
|
||||
LL| |
|
||||
LL| |// compile-flags: --edition=2021
|
||||
LL| |
|
||||
LL| |enum Never { }
|
||||
LL| |
|
||||
LL| |impl Never {
|
||||
LL| | fn foo(self) {
|
||||
LL| | match self { }
|
||||
LL| | make().map(|never| match never { });
|
||||
LL| | }
|
||||
LL| |
|
||||
LL| | fn bar(&self) {
|
||||
LL| | match *self { }
|
||||
LL| | }
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| 0|async fn foo2(never: Never) {
|
||||
LL| | match never { }
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| 0|fn make() -> Option<Never> {
|
||||
LL| 0| None
|
||||
LL| 0|}
|
||||
LL| |
|
||||
LL| 1|fn main() { }
|
||||
|
||||
|
|
|
@ -1,64 +1,64 @@
|
|||
1| |#![allow(unused_assignments, unused_variables)]
|
||||
2| |
|
||||
3| 1|fn main() {
|
||||
4| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
5| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
6| 1| // dependent conditions.
|
||||
7| 1| let is_true = std::env::args().len() == 1;
|
||||
8| 1|
|
||||
9| 1| let (mut a, mut b, mut c) = (0, 0, 0);
|
||||
10| 1| if is_true {
|
||||
11| 1| a = 1;
|
||||
12| 1| b = 10;
|
||||
13| 1| c = 100;
|
||||
14| 1| }
|
||||
LL| |#![allow(unused_assignments, unused_variables)]
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
LL| 1| // dependent conditions.
|
||||
LL| 1| let is_true = std::env::args().len() == 1;
|
||||
LL| 1|
|
||||
LL| 1| let (mut a, mut b, mut c) = (0, 0, 0);
|
||||
LL| 1| if is_true {
|
||||
LL| 1| a = 1;
|
||||
LL| 1| b = 10;
|
||||
LL| 1| c = 100;
|
||||
LL| 1| }
|
||||
^0
|
||||
15| | let
|
||||
16| 1| somebool
|
||||
17| | =
|
||||
18| 1| a < b
|
||||
19| | ||
|
||||
20| 0| b < c
|
||||
21| | ;
|
||||
22| | let
|
||||
23| 1| somebool
|
||||
24| | =
|
||||
25| 1| b < a
|
||||
26| | ||
|
||||
27| 1| b < c
|
||||
28| | ;
|
||||
29| 1| let somebool = a < b && b < c;
|
||||
30| 1| let somebool = b < a && b < c;
|
||||
LL| | let
|
||||
LL| 1| somebool
|
||||
LL| | =
|
||||
LL| 1| a < b
|
||||
LL| | ||
|
||||
LL| 0| b < c
|
||||
LL| | ;
|
||||
LL| | let
|
||||
LL| 1| somebool
|
||||
LL| | =
|
||||
LL| 1| b < a
|
||||
LL| | ||
|
||||
LL| 1| b < c
|
||||
LL| | ;
|
||||
LL| 1| let somebool = a < b && b < c;
|
||||
LL| 1| let somebool = b < a && b < c;
|
||||
^0
|
||||
31| |
|
||||
32| | if
|
||||
33| 1| !
|
||||
34| 1| is_true
|
||||
35| 0| {
|
||||
36| 0| a = 2
|
||||
37| 0| ;
|
||||
38| 1| }
|
||||
39| |
|
||||
40| | if
|
||||
41| 1| is_true
|
||||
42| 1| {
|
||||
43| 1| b = 30
|
||||
44| 1| ;
|
||||
45| 1| }
|
||||
46| | else
|
||||
47| 0| {
|
||||
48| 0| c = 400
|
||||
49| 0| ;
|
||||
50| 0| }
|
||||
51| |
|
||||
52| 1| if !is_true {
|
||||
53| 0| a = 2;
|
||||
54| 1| }
|
||||
55| |
|
||||
56| 1| if is_true {
|
||||
57| 1| b = 30;
|
||||
58| 1| } else {
|
||||
59| 0| c = 400;
|
||||
60| 0| }
|
||||
61| 1|}
|
||||
LL| |
|
||||
LL| | if
|
||||
LL| 1| !
|
||||
LL| 1| is_true
|
||||
LL| 0| {
|
||||
LL| 0| a = 2
|
||||
LL| 0| ;
|
||||
LL| 1| }
|
||||
LL| |
|
||||
LL| | if
|
||||
LL| 1| is_true
|
||||
LL| 1| {
|
||||
LL| 1| b = 30
|
||||
LL| 1| ;
|
||||
LL| 1| }
|
||||
LL| | else
|
||||
LL| 0| {
|
||||
LL| 0| c = 400
|
||||
LL| 0| ;
|
||||
LL| 0| }
|
||||
LL| |
|
||||
LL| 1| if !is_true {
|
||||
LL| 0| a = 2;
|
||||
LL| 1| }
|
||||
LL| |
|
||||
LL| 1| if is_true {
|
||||
LL| 1| b = 30;
|
||||
LL| 1| } else {
|
||||
LL| 0| c = 400;
|
||||
LL| 0| }
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
1| |#![allow(unused_assignments, unused_variables)]
|
||||
2| |
|
||||
3| 1|fn main() {
|
||||
4| 1| let result
|
||||
5| 1| =
|
||||
6| 1| loop
|
||||
7| 1| {
|
||||
8| 1| break
|
||||
9| 1| 10
|
||||
10| 1| ;
|
||||
11| 1| }
|
||||
12| 1| ;
|
||||
13| 1|}
|
||||
LL| |#![allow(unused_assignments, unused_variables)]
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| let result
|
||||
LL| 1| =
|
||||
LL| 1| loop
|
||||
LL| 1| {
|
||||
LL| 1| break
|
||||
LL| 1| 10
|
||||
LL| 1| ;
|
||||
LL| 1| }
|
||||
LL| 1| ;
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,68 +1,68 @@
|
|||
1| |#![allow(unused_assignments, unused_variables, while_true)]
|
||||
2| |
|
||||
3| |// This test confirms that (1) unexecuted infinite loops are handled correctly by the
|
||||
4| |// InstrumentCoverage MIR pass; and (2) Counter Expressions that subtract from zero can be dropped.
|
||||
5| |
|
||||
6| |struct DebugTest;
|
||||
7| |
|
||||
8| |impl std::fmt::Debug for DebugTest {
|
||||
9| 1| fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
10| 1| if true {
|
||||
11| 1| if false {
|
||||
12| 0| while true {
|
||||
13| 0| }
|
||||
14| 1| }
|
||||
15| 1| write!(f, "cool")?;
|
||||
LL| |#![allow(unused_assignments, unused_variables, while_true)]
|
||||
LL| |
|
||||
LL| |// This test confirms that (1) unexecuted infinite loops are handled correctly by the
|
||||
LL| |// InstrumentCoverage MIR pass; and (2) Counter Expressions that subtract from zero can be dropped.
|
||||
LL| |
|
||||
LL| |struct DebugTest;
|
||||
LL| |
|
||||
LL| |impl std::fmt::Debug for DebugTest {
|
||||
LL| 1| fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
LL| 1| if true {
|
||||
LL| 1| if false {
|
||||
LL| 0| while true {
|
||||
LL| 0| }
|
||||
LL| 1| }
|
||||
LL| 1| write!(f, "cool")?;
|
||||
^0
|
||||
16| 0| } else {
|
||||
17| 0| }
|
||||
18| |
|
||||
19| 11| for i in 0..10 {
|
||||
LL| 0| } else {
|
||||
LL| 0| }
|
||||
LL| |
|
||||
LL| 11| for i in 0..10 {
|
||||
^10
|
||||
20| 10| if true {
|
||||
21| 10| if false {
|
||||
22| 0| while true {}
|
||||
23| 10| }
|
||||
24| 10| write!(f, "cool")?;
|
||||
LL| 10| if true {
|
||||
LL| 10| if false {
|
||||
LL| 0| while true {}
|
||||
LL| 10| }
|
||||
LL| 10| write!(f, "cool")?;
|
||||
^0
|
||||
25| 0| } else {
|
||||
26| 0| }
|
||||
27| | }
|
||||
28| 1| Ok(())
|
||||
29| 1| }
|
||||
30| |}
|
||||
31| |
|
||||
32| |struct DisplayTest;
|
||||
33| |
|
||||
34| |impl std::fmt::Display for DisplayTest {
|
||||
35| 1| fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
36| 1| if false {
|
||||
37| 0| } else {
|
||||
38| 1| if false {
|
||||
39| 0| while true {}
|
||||
40| 1| }
|
||||
41| 1| write!(f, "cool")?;
|
||||
LL| 0| } else {
|
||||
LL| 0| }
|
||||
LL| | }
|
||||
LL| 1| Ok(())
|
||||
LL| 1| }
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| |struct DisplayTest;
|
||||
LL| |
|
||||
LL| |impl std::fmt::Display for DisplayTest {
|
||||
LL| 1| fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
LL| 1| if false {
|
||||
LL| 0| } else {
|
||||
LL| 1| if false {
|
||||
LL| 0| while true {}
|
||||
LL| 1| }
|
||||
LL| 1| write!(f, "cool")?;
|
||||
^0
|
||||
42| | }
|
||||
43| 11| for i in 0..10 {
|
||||
LL| | }
|
||||
LL| 11| for i in 0..10 {
|
||||
^10
|
||||
44| 10| if false {
|
||||
45| 0| } else {
|
||||
46| 10| if false {
|
||||
47| 0| while true {}
|
||||
48| 10| }
|
||||
49| 10| write!(f, "cool")?;
|
||||
LL| 10| if false {
|
||||
LL| 0| } else {
|
||||
LL| 10| if false {
|
||||
LL| 0| while true {}
|
||||
LL| 10| }
|
||||
LL| 10| write!(f, "cool")?;
|
||||
^0
|
||||
50| | }
|
||||
51| | }
|
||||
52| 1| Ok(())
|
||||
53| 1| }
|
||||
54| |}
|
||||
55| |
|
||||
56| 1|fn main() {
|
||||
57| 1| let debug_test = DebugTest;
|
||||
58| 1| println!("{:?}", debug_test);
|
||||
59| 1| let display_test = DisplayTest;
|
||||
60| 1| println!("{}", display_test);
|
||||
61| 1|}
|
||||
LL| | }
|
||||
LL| | }
|
||||
LL| 1| Ok(())
|
||||
LL| 1| }
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| let debug_test = DebugTest;
|
||||
LL| 1| println!("{:?}", debug_test);
|
||||
LL| 1| let display_test = DisplayTest;
|
||||
LL| 1| println!("{}", display_test);
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,50 +1,50 @@
|
|||
1| |#![feature(or_patterns)]
|
||||
2| |
|
||||
3| 1|fn main() {
|
||||
4| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
5| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
6| 1| // dependent conditions.
|
||||
7| 1| let is_true = std::env::args().len() == 1;
|
||||
8| 1|
|
||||
9| 1| let mut a: u8 = 0;
|
||||
10| 1| let mut b: u8 = 0;
|
||||
11| 1| if is_true {
|
||||
12| 1| a = 2;
|
||||
13| 1| b = 0;
|
||||
14| 1| }
|
||||
LL| |#![feature(or_patterns)]
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
LL| 1| // dependent conditions.
|
||||
LL| 1| let is_true = std::env::args().len() == 1;
|
||||
LL| 1|
|
||||
LL| 1| let mut a: u8 = 0;
|
||||
LL| 1| let mut b: u8 = 0;
|
||||
LL| 1| if is_true {
|
||||
LL| 1| a = 2;
|
||||
LL| 1| b = 0;
|
||||
LL| 1| }
|
||||
^0
|
||||
15| 1| match (a, b) {
|
||||
16| | // Or patterns generate MIR `SwitchInt` with multiple targets to the same `BasicBlock`.
|
||||
17| | // This test confirms a fix for Issue #79569.
|
||||
18| 0| (0 | 1, 2 | 3) => {}
|
||||
19| 1| _ => {}
|
||||
20| | }
|
||||
21| 1| if is_true {
|
||||
22| 1| a = 0;
|
||||
23| 1| b = 0;
|
||||
24| 1| }
|
||||
LL| 1| match (a, b) {
|
||||
LL| | // Or patterns generate MIR `SwitchInt` with multiple targets to the same `BasicBlock`.
|
||||
LL| | // This test confirms a fix for Issue #79569.
|
||||
LL| 0| (0 | 1, 2 | 3) => {}
|
||||
LL| 1| _ => {}
|
||||
LL| | }
|
||||
LL| 1| if is_true {
|
||||
LL| 1| a = 0;
|
||||
LL| 1| b = 0;
|
||||
LL| 1| }
|
||||
^0
|
||||
25| 1| match (a, b) {
|
||||
26| 0| (0 | 1, 2 | 3) => {}
|
||||
27| 1| _ => {}
|
||||
28| | }
|
||||
29| 1| if is_true {
|
||||
30| 1| a = 2;
|
||||
31| 1| b = 2;
|
||||
32| 1| }
|
||||
LL| 1| match (a, b) {
|
||||
LL| 0| (0 | 1, 2 | 3) => {}
|
||||
LL| 1| _ => {}
|
||||
LL| | }
|
||||
LL| 1| if is_true {
|
||||
LL| 1| a = 2;
|
||||
LL| 1| b = 2;
|
||||
LL| 1| }
|
||||
^0
|
||||
33| 1| match (a, b) {
|
||||
34| 0| (0 | 1, 2 | 3) => {}
|
||||
35| 1| _ => {}
|
||||
36| | }
|
||||
37| 1| if is_true {
|
||||
38| 1| a = 0;
|
||||
39| 1| b = 2;
|
||||
40| 1| }
|
||||
LL| 1| match (a, b) {
|
||||
LL| 0| (0 | 1, 2 | 3) => {}
|
||||
LL| 1| _ => {}
|
||||
LL| | }
|
||||
LL| 1| if is_true {
|
||||
LL| 1| a = 0;
|
||||
LL| 1| b = 2;
|
||||
LL| 1| }
|
||||
^0
|
||||
41| 1| match (a, b) {
|
||||
42| 1| (0 | 1, 2 | 3) => {}
|
||||
43| 0| _ => {}
|
||||
44| | }
|
||||
45| 1|}
|
||||
LL| 1| match (a, b) {
|
||||
LL| 1| (0 | 1, 2 | 3) => {}
|
||||
LL| 0| _ => {}
|
||||
LL| | }
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
1| 1|fn main() {
|
||||
2| 1| let is_true = std::env::args().len() == 1;
|
||||
3| 1| let mut countdown = 10;
|
||||
4| |
|
||||
5| 1| 'outer: while countdown > 0 {
|
||||
6| 1| let mut a = 100;
|
||||
7| 1| let mut b = 100;
|
||||
8| 3| for _ in 0..50 {
|
||||
9| 3| if a < 30 {
|
||||
10| 0| break;
|
||||
11| 3| }
|
||||
12| 3| a -= 5;
|
||||
13| 3| b -= 5;
|
||||
14| 3| if b < 90 {
|
||||
15| 1| a -= 10;
|
||||
16| 1| if is_true {
|
||||
17| 1| break 'outer;
|
||||
18| 0| } else {
|
||||
19| 0| a -= 2;
|
||||
20| 0| }
|
||||
21| 2| }
|
||||
22| | }
|
||||
23| 0| countdown -= 1;
|
||||
24| | }
|
||||
25| 1|}
|
||||
LL| 1|fn main() {
|
||||
LL| 1| let is_true = std::env::args().len() == 1;
|
||||
LL| 1| let mut countdown = 10;
|
||||
LL| |
|
||||
LL| 1| 'outer: while countdown > 0 {
|
||||
LL| 1| let mut a = 100;
|
||||
LL| 1| let mut b = 100;
|
||||
LL| 3| for _ in 0..50 {
|
||||
LL| 3| if a < 30 {
|
||||
LL| 0| break;
|
||||
LL| 3| }
|
||||
LL| 3| a -= 5;
|
||||
LL| 3| b -= 5;
|
||||
LL| 3| if b < 90 {
|
||||
LL| 1| a -= 10;
|
||||
LL| 1| if is_true {
|
||||
LL| 1| break 'outer;
|
||||
LL| 0| } else {
|
||||
LL| 0| a -= 2;
|
||||
LL| 0| }
|
||||
LL| 2| }
|
||||
LL| | }
|
||||
LL| 0| countdown -= 1;
|
||||
LL| | }
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,87 +1,87 @@
|
|||
1| |// Enables `no_coverage` on the entire crate
|
||||
2| |#![feature(no_coverage)]
|
||||
3| |
|
||||
4| |#[no_coverage]
|
||||
5| |fn do_not_add_coverage_1() {
|
||||
6| | println!("called but not covered");
|
||||
7| |}
|
||||
8| |
|
||||
9| |fn do_not_add_coverage_2() {
|
||||
10| | #![no_coverage]
|
||||
11| | println!("called but not covered");
|
||||
12| |}
|
||||
13| |
|
||||
14| |#[no_coverage]
|
||||
15| |fn do_not_add_coverage_not_called() {
|
||||
16| | println!("not called and not covered");
|
||||
17| |}
|
||||
18| |
|
||||
19| 1|fn add_coverage_1() {
|
||||
20| 1| println!("called and covered");
|
||||
21| 1|}
|
||||
22| |
|
||||
23| 1|fn add_coverage_2() {
|
||||
24| 1| println!("called and covered");
|
||||
25| 1|}
|
||||
26| |
|
||||
27| 0|fn add_coverage_not_called() {
|
||||
28| 0| println!("not called but covered");
|
||||
29| 0|}
|
||||
30| |
|
||||
31| |// FIXME: These test-cases illustrate confusing results of nested functions.
|
||||
32| |// See https://github.com/rust-lang/rust/issues/93319
|
||||
33| |mod nested_fns {
|
||||
34| | #[no_coverage]
|
||||
35| | pub fn outer_not_covered(is_true: bool) {
|
||||
36| 1| fn inner(is_true: bool) {
|
||||
37| 1| if is_true {
|
||||
38| 1| println!("called and covered");
|
||||
39| 1| } else {
|
||||
40| 0| println!("absolutely not covered");
|
||||
41| 0| }
|
||||
42| 1| }
|
||||
43| | println!("called but not covered");
|
||||
44| | inner(is_true);
|
||||
45| | }
|
||||
46| |
|
||||
47| 1| pub fn outer(is_true: bool) {
|
||||
48| 1| println!("called and covered");
|
||||
49| 1| inner_not_covered(is_true);
|
||||
50| 1|
|
||||
51| 1| #[no_coverage]
|
||||
52| 1| fn inner_not_covered(is_true: bool) {
|
||||
53| 1| if is_true {
|
||||
54| 1| println!("called but not covered");
|
||||
55| 1| } else {
|
||||
56| 1| println!("absolutely not covered");
|
||||
57| 1| }
|
||||
58| 1| }
|
||||
59| 1| }
|
||||
60| |
|
||||
61| 1| pub fn outer_both_covered(is_true: bool) {
|
||||
62| 1| println!("called and covered");
|
||||
63| 1| inner(is_true);
|
||||
64| 1|
|
||||
65| 1| fn inner(is_true: bool) {
|
||||
66| 1| if is_true {
|
||||
67| 1| println!("called and covered");
|
||||
68| 1| } else {
|
||||
69| 0| println!("absolutely not covered");
|
||||
70| 0| }
|
||||
71| 1| }
|
||||
72| 1| }
|
||||
73| |}
|
||||
74| |
|
||||
75| 1|fn main() {
|
||||
76| 1| let is_true = std::env::args().len() == 1;
|
||||
77| 1|
|
||||
78| 1| do_not_add_coverage_1();
|
||||
79| 1| do_not_add_coverage_2();
|
||||
80| 1| add_coverage_1();
|
||||
81| 1| add_coverage_2();
|
||||
82| 1|
|
||||
83| 1| nested_fns::outer_not_covered(is_true);
|
||||
84| 1| nested_fns::outer(is_true);
|
||||
85| 1| nested_fns::outer_both_covered(is_true);
|
||||
86| 1|}
|
||||
LL| |// Enables `no_coverage` on the entire crate
|
||||
LL| |#![feature(no_coverage)]
|
||||
LL| |
|
||||
LL| |#[no_coverage]
|
||||
LL| |fn do_not_add_coverage_1() {
|
||||
LL| | println!("called but not covered");
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| |fn do_not_add_coverage_2() {
|
||||
LL| | #![no_coverage]
|
||||
LL| | println!("called but not covered");
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| |#[no_coverage]
|
||||
LL| |fn do_not_add_coverage_not_called() {
|
||||
LL| | println!("not called and not covered");
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| 1|fn add_coverage_1() {
|
||||
LL| 1| println!("called and covered");
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| 1|fn add_coverage_2() {
|
||||
LL| 1| println!("called and covered");
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| 0|fn add_coverage_not_called() {
|
||||
LL| 0| println!("not called but covered");
|
||||
LL| 0|}
|
||||
LL| |
|
||||
LL| |// FIXME: These test-cases illustrate confusing results of nested functions.
|
||||
LL| |// See https://github.com/rust-lang/rust/issues/93319
|
||||
LL| |mod nested_fns {
|
||||
LL| | #[no_coverage]
|
||||
LL| | pub fn outer_not_covered(is_true: bool) {
|
||||
LL| 1| fn inner(is_true: bool) {
|
||||
LL| 1| if is_true {
|
||||
LL| 1| println!("called and covered");
|
||||
LL| 1| } else {
|
||||
LL| 0| println!("absolutely not covered");
|
||||
LL| 0| }
|
||||
LL| 1| }
|
||||
LL| | println!("called but not covered");
|
||||
LL| | inner(is_true);
|
||||
LL| | }
|
||||
LL| |
|
||||
LL| 1| pub fn outer(is_true: bool) {
|
||||
LL| 1| println!("called and covered");
|
||||
LL| 1| inner_not_covered(is_true);
|
||||
LL| 1|
|
||||
LL| 1| #[no_coverage]
|
||||
LL| 1| fn inner_not_covered(is_true: bool) {
|
||||
LL| 1| if is_true {
|
||||
LL| 1| println!("called but not covered");
|
||||
LL| 1| } else {
|
||||
LL| 1| println!("absolutely not covered");
|
||||
LL| 1| }
|
||||
LL| 1| }
|
||||
LL| 1| }
|
||||
LL| |
|
||||
LL| 1| pub fn outer_both_covered(is_true: bool) {
|
||||
LL| 1| println!("called and covered");
|
||||
LL| 1| inner(is_true);
|
||||
LL| 1|
|
||||
LL| 1| fn inner(is_true: bool) {
|
||||
LL| 1| if is_true {
|
||||
LL| 1| println!("called and covered");
|
||||
LL| 1| } else {
|
||||
LL| 0| println!("absolutely not covered");
|
||||
LL| 0| }
|
||||
LL| 1| }
|
||||
LL| 1| }
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| let is_true = std::env::args().len() == 1;
|
||||
LL| 1|
|
||||
LL| 1| do_not_add_coverage_1();
|
||||
LL| 1| do_not_add_coverage_2();
|
||||
LL| 1| add_coverage_1();
|
||||
LL| 1| add_coverage_2();
|
||||
LL| 1|
|
||||
LL| 1| nested_fns::outer_not_covered(is_true);
|
||||
LL| 1| nested_fns::outer(is_true);
|
||||
LL| 1| nested_fns::outer_both_covered(is_true);
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,64 +1,64 @@
|
|||
1| |#![allow(unused_assignments)]
|
||||
2| |// failure-status: 101
|
||||
3| |
|
||||
4| 4|fn might_overflow(to_add: u32) -> u32 {
|
||||
5| 4| if to_add > 5 {
|
||||
6| 1| println!("this will probably overflow");
|
||||
7| 3| }
|
||||
8| 4| let add_to = u32::MAX - 5;
|
||||
9| 4| println!("does {} + {} overflow?", add_to, to_add);
|
||||
10| 4| let result = to_add + add_to;
|
||||
11| 4| println!("continuing after overflow check");
|
||||
12| 4| result
|
||||
13| 4|}
|
||||
14| |
|
||||
15| 1|fn main() -> Result<(),u8> {
|
||||
16| 1| let mut countdown = 10;
|
||||
17| 11| while countdown > 0 {
|
||||
18| 11| if countdown == 1 {
|
||||
19| 1| let result = might_overflow(10);
|
||||
20| 1| println!("Result: {}", result);
|
||||
21| 10| } else if countdown < 5 {
|
||||
22| 3| let result = might_overflow(1);
|
||||
23| 3| println!("Result: {}", result);
|
||||
24| 6| }
|
||||
25| 10| countdown -= 1;
|
||||
26| | }
|
||||
27| 0| Ok(())
|
||||
28| 0|}
|
||||
29| |
|
||||
30| |// Notes:
|
||||
31| |// 1. Compare this program and its coverage results to those of the very similar test `assert.rs`,
|
||||
32| |// and similar tests `panic_unwind.rs`, abort.rs` and `try_error_result.rs`.
|
||||
33| |// 2. This test confirms the coverage generated when a program passes or fails a
|
||||
34| |// compiler-generated `TerminatorKind::Assert` (based on an overflow check, in this case).
|
||||
35| |// 3. Similar to how the coverage instrumentation handles `TerminatorKind::Call`,
|
||||
36| |// compiler-generated assertion failures are assumed to be a symptom of a program bug, not
|
||||
37| |// expected behavior. To simplify the coverage graphs and keep instrumented programs as
|
||||
38| |// small and fast as possible, `Assert` terminators are assumed to always succeed, and
|
||||
39| |// therefore are considered "non-branching" terminators. So, an `Assert` terminator does not
|
||||
40| |// get its own coverage counter.
|
||||
41| |// 4. After an unhandled panic or failed Assert, coverage results may not always be intuitive.
|
||||
42| |// In this test, the final count for the statements after the `if` block in `might_overflow()`
|
||||
43| |// is 4, even though the lines after `to_add + add_to` were executed only 3 times. Depending
|
||||
44| |// on the MIR graph and the structure of the code, this count could have been 3 (which might
|
||||
45| |// have been valid for the overflowed add `+`, but should have been 4 for the lines before
|
||||
46| |// the overflow. The reason for this potential uncertainty is, a `CounterKind` is incremented
|
||||
47| |// via StatementKind::Counter at the end of the block, but (as in the case in this test),
|
||||
48| |// a CounterKind::Expression is always evaluated. In this case, the expression was based on
|
||||
49| |// a `Counter` incremented as part of the evaluation of the `if` expression, which was
|
||||
50| |// executed, and counted, 4 times, before reaching the overflow add.
|
||||
51| |
|
||||
52| |// If the program did not overflow, the coverage for `might_overflow()` would look like this:
|
||||
53| |//
|
||||
54| |// 4| |fn might_overflow(to_add: u32) -> u32 {
|
||||
55| |// 5| 4| if to_add > 5 {
|
||||
56| |// 6| 0| println!("this will probably overflow");
|
||||
57| |// 7| 4| }
|
||||
58| |// 8| 4| let add_to = u32::MAX - 5;
|
||||
59| |// 9| 4| println!("does {} + {} overflow?", add_to, to_add);
|
||||
60| |// 10| 4| let result = to_add + add_to;
|
||||
61| |// 11| 4| println!("continuing after overflow check");
|
||||
62| |// 12| 4| result
|
||||
63| |// 13| 4|}
|
||||
LL| |#![allow(unused_assignments)]
|
||||
LL| |// failure-status: 101
|
||||
LL| |
|
||||
LL| 4|fn might_overflow(to_add: u32) -> u32 {
|
||||
LL| 4| if to_add > 5 {
|
||||
LL| 1| println!("this will probably overflow");
|
||||
LL| 3| }
|
||||
LL| 4| let add_to = u32::MAX - 5;
|
||||
LL| 4| println!("does {} + {} overflow?", add_to, to_add);
|
||||
LL| 4| let result = to_add + add_to;
|
||||
LL| 4| println!("continuing after overflow check");
|
||||
LL| 4| result
|
||||
LL| 4|}
|
||||
LL| |
|
||||
LL| 1|fn main() -> Result<(),u8> {
|
||||
LL| 1| let mut countdown = 10;
|
||||
LL| 11| while countdown > 0 {
|
||||
LL| 11| if countdown == 1 {
|
||||
LL| 1| let result = might_overflow(10);
|
||||
LL| 1| println!("Result: {}", result);
|
||||
LL| 10| } else if countdown < 5 {
|
||||
LL| 3| let result = might_overflow(1);
|
||||
LL| 3| println!("Result: {}", result);
|
||||
LL| 6| }
|
||||
LL| 10| countdown -= 1;
|
||||
LL| | }
|
||||
LL| 0| Ok(())
|
||||
LL| 0|}
|
||||
LL| |
|
||||
LL| |// Notes:
|
||||
LL| |// 1. Compare this program and its coverage results to those of the very similar test `assert.rs`,
|
||||
LL| |// and similar tests `panic_unwind.rs`, abort.rs` and `try_error_result.rs`.
|
||||
LL| |// 2. This test confirms the coverage generated when a program passes or fails a
|
||||
LL| |// compiler-generated `TerminatorKind::Assert` (based on an overflow check, in this case).
|
||||
LL| |// 3. Similar to how the coverage instrumentation handles `TerminatorKind::Call`,
|
||||
LL| |// compiler-generated assertion failures are assumed to be a symptom of a program bug, not
|
||||
LL| |// expected behavior. To simplify the coverage graphs and keep instrumented programs as
|
||||
LL| |// small and fast as possible, `Assert` terminators are assumed to always succeed, and
|
||||
LL| |// therefore are considered "non-branching" terminators. So, an `Assert` terminator does not
|
||||
LL| |// get its own coverage counter.
|
||||
LL| |// 4. After an unhandled panic or failed Assert, coverage results may not always be intuitive.
|
||||
LL| |// In this test, the final count for the statements after the `if` block in `might_overflow()`
|
||||
LL| |// is 4, even though the lines after `to_add + add_to` were executed only 3 times. Depending
|
||||
LL| |// on the MIR graph and the structure of the code, this count could have been 3 (which might
|
||||
LL| |// have been valid for the overflowed add `+`, but should have been 4 for the lines before
|
||||
LL| |// the overflow. The reason for this potential uncertainty is, a `CounterKind` is incremented
|
||||
LL| |// via StatementKind::Counter at the end of the block, but (as in the case in this test),
|
||||
LL| |// a CounterKind::Expression is always evaluated. In this case, the expression was based on
|
||||
LL| |// a `Counter` incremented as part of the evaluation of the `if` expression, which was
|
||||
LL| |// executed, and counted, 4 times, before reaching the overflow add.
|
||||
LL| |
|
||||
LL| |// If the program did not overflow, the coverage for `might_overflow()` would look like this:
|
||||
LL| |//
|
||||
LL| |// 4| |fn might_overflow(to_add: u32) -> u32 {
|
||||
LL| |// 5| 4| if to_add > 5 {
|
||||
LL| |// 6| 0| println!("this will probably overflow");
|
||||
LL| |// 7| 4| }
|
||||
LL| |// 8| 4| let add_to = u32::MAX - 5;
|
||||
LL| |// 9| 4| println!("does {} + {} overflow?", add_to, to_add);
|
||||
LL| |// 10| 4| let result = to_add + add_to;
|
||||
LL| |// 11| 4| println!("continuing after overflow check");
|
||||
LL| |// 12| 4| result
|
||||
LL| |// 13| 4|}
|
||||
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
1| |#![allow(unused_assignments)]
|
||||
2| |// failure-status: 101
|
||||
3| |
|
||||
4| 4|fn might_panic(should_panic: bool) {
|
||||
5| 4| if should_panic {
|
||||
6| 1| println!("panicking...");
|
||||
7| 1| panic!("panics");
|
||||
8| 3| } else {
|
||||
9| 3| println!("Don't Panic");
|
||||
10| 3| }
|
||||
11| 3|}
|
||||
12| |
|
||||
13| 1|fn main() -> Result<(), u8> {
|
||||
14| 1| let mut countdown = 10;
|
||||
15| 11| while countdown > 0 {
|
||||
16| 11| if countdown == 1 {
|
||||
17| 1| might_panic(true);
|
||||
18| 10| } else if countdown < 5 {
|
||||
19| 3| might_panic(false);
|
||||
20| 6| }
|
||||
21| 10| countdown -= 1;
|
||||
22| | }
|
||||
23| 0| Ok(())
|
||||
24| 0|}
|
||||
25| |
|
||||
26| |// Notes:
|
||||
27| |// 1. Compare this program and its coverage results to those of the similar tests `abort.rs` and
|
||||
28| |// `try_error_result.rs`.
|
||||
29| |// 2. Since the `panic_unwind.rs` test is allowed to unwind, it is also allowed to execute the
|
||||
30| |// normal program exit cleanup, including writing out the current values of the coverage
|
||||
31| |// counters.
|
||||
LL| |#![allow(unused_assignments)]
|
||||
LL| |// failure-status: 101
|
||||
LL| |
|
||||
LL| 4|fn might_panic(should_panic: bool) {
|
||||
LL| 4| if should_panic {
|
||||
LL| 1| println!("panicking...");
|
||||
LL| 1| panic!("panics");
|
||||
LL| 3| } else {
|
||||
LL| 3| println!("Don't Panic");
|
||||
LL| 3| }
|
||||
LL| 3|}
|
||||
LL| |
|
||||
LL| 1|fn main() -> Result<(), u8> {
|
||||
LL| 1| let mut countdown = 10;
|
||||
LL| 11| while countdown > 0 {
|
||||
LL| 11| if countdown == 1 {
|
||||
LL| 1| might_panic(true);
|
||||
LL| 10| } else if countdown < 5 {
|
||||
LL| 3| might_panic(false);
|
||||
LL| 6| }
|
||||
LL| 10| countdown -= 1;
|
||||
LL| | }
|
||||
LL| 0| Ok(())
|
||||
LL| 0|}
|
||||
LL| |
|
||||
LL| |// Notes:
|
||||
LL| |// 1. Compare this program and its coverage results to those of the similar tests `abort.rs` and
|
||||
LL| |// `try_error_result.rs`.
|
||||
LL| |// 2. Since the `panic_unwind.rs` test is allowed to unwind, it is also allowed to execute the
|
||||
LL| |// normal program exit cleanup, including writing out the current values of the coverage
|
||||
LL| |// counters.
|
||||
|
||||
|
|
|
@ -1,48 +1,48 @@
|
|||
1| |// This test confirms an earlier problem was resolved, supporting the MIR graph generated by the
|
||||
2| |// structure of this test.
|
||||
3| |
|
||||
4| 2|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
LL| |// This test confirms an earlier problem was resolved, supporting the MIR graph generated by the
|
||||
LL| |// structure of this test.
|
||||
LL| |
|
||||
LL| 2|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
^0 ^0 ^0 ^1 ^1 ^0^0
|
||||
5| |pub struct Version {
|
||||
6| | major: usize,
|
||||
7| | minor: usize,
|
||||
8| | patch: usize,
|
||||
9| |}
|
||||
10| |
|
||||
11| |impl Version {
|
||||
12| 2| pub fn new(major: usize, minor: usize, patch: usize) -> Self {
|
||||
13| 2| Self {
|
||||
14| 2| major,
|
||||
15| 2| minor,
|
||||
16| 2| patch,
|
||||
17| 2| }
|
||||
18| 2| }
|
||||
19| |}
|
||||
20| |
|
||||
21| 1|fn main() {
|
||||
22| 1| let version_3_2_1 = Version::new(3, 2, 1);
|
||||
23| 1| let version_3_3_0 = Version::new(3, 3, 0);
|
||||
24| 1|
|
||||
25| 1| println!("{:?} < {:?} = {}", version_3_2_1, version_3_3_0, version_3_2_1 < version_3_3_0);
|
||||
26| 1|}
|
||||
27| |
|
||||
28| |/*
|
||||
29| |
|
||||
30| |This test verifies a bug was fixed that otherwise generated this error:
|
||||
31| |
|
||||
32| |thread 'rustc' panicked at 'No counters provided the source_hash for function:
|
||||
33| | Instance {
|
||||
34| | def: Item(WithOptConstParam {
|
||||
35| | did: DefId(0:101 ~ autocfg[c44a]::version::{impl#2}::partial_cmp),
|
||||
36| | const_param_did: None
|
||||
37| | }),
|
||||
38| | args: []
|
||||
39| | }'
|
||||
40| |The `PartialOrd` derived by `Version` happened to generate a MIR that generated coverage
|
||||
41| |without a code region associated with any `Counter`. Code regions were associated with at least
|
||||
42| |one expression, which is allowed, but the `function_source_hash` was only passed to the codegen
|
||||
43| |(coverage mapgen) phase from a `Counter`s code region. A new method was added to pass the
|
||||
44| |`function_source_hash` without a code region, if necessary.
|
||||
45| |
|
||||
46| |*/
|
||||
LL| |pub struct Version {
|
||||
LL| | major: usize,
|
||||
LL| | minor: usize,
|
||||
LL| | patch: usize,
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| |impl Version {
|
||||
LL| 2| pub fn new(major: usize, minor: usize, patch: usize) -> Self {
|
||||
LL| 2| Self {
|
||||
LL| 2| major,
|
||||
LL| 2| minor,
|
||||
LL| 2| patch,
|
||||
LL| 2| }
|
||||
LL| 2| }
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| let version_3_2_1 = Version::new(3, 2, 1);
|
||||
LL| 1| let version_3_3_0 = Version::new(3, 3, 0);
|
||||
LL| 1|
|
||||
LL| 1| println!("{:?} < {:?} = {}", version_3_2_1, version_3_3_0, version_3_2_1 < version_3_3_0);
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| |/*
|
||||
LL| |
|
||||
LL| |This test verifies a bug was fixed that otherwise generated this error:
|
||||
LL| |
|
||||
LL| |thread 'rustc' panicked at 'No counters provided the source_hash for function:
|
||||
LL| | Instance {
|
||||
LL| | def: Item(WithOptConstParam {
|
||||
LL| | did: DefId(0:101 ~ autocfg[c44a]::version::{impl#2}::partial_cmp),
|
||||
LL| | const_param_did: None
|
||||
LL| | }),
|
||||
LL| | args: []
|
||||
LL| | }'
|
||||
LL| |The `PartialOrd` derived by `Version` happened to generate a MIR that generated coverage
|
||||
LL| |without a code region associated with any `Counter`. Code regions were associated with at least
|
||||
LL| |one expression, which is allowed, but the `function_source_hash` was only passed to the codegen
|
||||
LL| |(coverage mapgen) phase from a `Counter`s code region. A new method was added to pass the
|
||||
LL| |`function_source_hash` without a code region, if necessary.
|
||||
LL| |
|
||||
LL| |*/
|
||||
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
1| |#![allow(unused_assignments)]
|
||||
2| |
|
||||
3| 1|fn main() {
|
||||
4| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
5| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
6| 1| // dependent conditions.
|
||||
7| 1| let is_true = std::env::args().len() == 1;
|
||||
8| 1|
|
||||
9| 1| let mut countdown = 0;
|
||||
10| 1|
|
||||
11| 1| if
|
||||
12| 1| is_true
|
||||
13| 1| {
|
||||
14| 1| countdown
|
||||
15| 1| =
|
||||
16| 1| 10
|
||||
17| 1| ;
|
||||
18| 1| }
|
||||
LL| |#![allow(unused_assignments)]
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
LL| 1| // dependent conditions.
|
||||
LL| 1| let is_true = std::env::args().len() == 1;
|
||||
LL| 1|
|
||||
LL| 1| let mut countdown = 0;
|
||||
LL| 1|
|
||||
LL| 1| if
|
||||
LL| 1| is_true
|
||||
LL| 1| {
|
||||
LL| 1| countdown
|
||||
LL| 1| =
|
||||
LL| 1| 10
|
||||
LL| 1| ;
|
||||
LL| 1| }
|
||||
^0
|
||||
19| |
|
||||
20| | loop
|
||||
21| | {
|
||||
22| | if
|
||||
23| 11| countdown
|
||||
24| 11| ==
|
||||
25| 11| 0
|
||||
26| | {
|
||||
27| 1| break
|
||||
28| | ;
|
||||
29| 10| }
|
||||
30| 10| countdown
|
||||
31| 10| -=
|
||||
32| 10| 1
|
||||
33| | ;
|
||||
34| | }
|
||||
35| 1|}
|
||||
LL| |
|
||||
LL| | loop
|
||||
LL| | {
|
||||
LL| | if
|
||||
LL| 11| countdown
|
||||
LL| 11| ==
|
||||
LL| 11| 0
|
||||
LL| | {
|
||||
LL| 1| break
|
||||
LL| | ;
|
||||
LL| 10| }
|
||||
LL| 10| countdown
|
||||
LL| 10| -=
|
||||
LL| 10| 1
|
||||
LL| | ;
|
||||
LL| | }
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,45 +1,45 @@
|
|||
1| |#![allow(unused_assignments, unused_variables)]
|
||||
2| |
|
||||
3| 1|fn main() {
|
||||
4| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
5| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
6| 1| // dependent conditions.
|
||||
7| 1| let is_true = std::env::args().len() == 1;
|
||||
8| 1|
|
||||
9| 1| let mut countdown = 1;
|
||||
10| 1| if is_true {
|
||||
11| 1| countdown = 0;
|
||||
12| 1| }
|
||||
LL| |#![allow(unused_assignments, unused_variables)]
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
LL| 1| // dependent conditions.
|
||||
LL| 1| let is_true = std::env::args().len() == 1;
|
||||
LL| 1|
|
||||
LL| 1| let mut countdown = 1;
|
||||
LL| 1| if is_true {
|
||||
LL| 1| countdown = 0;
|
||||
LL| 1| }
|
||||
^0
|
||||
13| |
|
||||
14| | for
|
||||
15| | _
|
||||
16| | in
|
||||
17| 3| 0..2
|
||||
18| | {
|
||||
19| | let z
|
||||
20| | ;
|
||||
21| | match
|
||||
22| 2| countdown
|
||||
23| | {
|
||||
24| 1| x
|
||||
25| | if
|
||||
26| 2| x
|
||||
27| 2| <
|
||||
28| 2| 1
|
||||
29| | =>
|
||||
30| 1| {
|
||||
31| 1| z = countdown
|
||||
32| 1| ;
|
||||
33| 1| let y = countdown
|
||||
34| 1| ;
|
||||
35| 1| countdown = 10
|
||||
36| 1| ;
|
||||
37| 1| }
|
||||
38| | _
|
||||
39| | =>
|
||||
40| 1| {}
|
||||
41| | }
|
||||
42| | }
|
||||
43| 1|}
|
||||
LL| |
|
||||
LL| | for
|
||||
LL| | _
|
||||
LL| | in
|
||||
LL| 3| 0..2
|
||||
LL| | {
|
||||
LL| | let z
|
||||
LL| | ;
|
||||
LL| | match
|
||||
LL| 2| countdown
|
||||
LL| | {
|
||||
LL| 1| x
|
||||
LL| | if
|
||||
LL| 2| x
|
||||
LL| 2| <
|
||||
LL| 2| 1
|
||||
LL| | =>
|
||||
LL| 1| {
|
||||
LL| 1| z = countdown
|
||||
LL| 1| ;
|
||||
LL| 1| let y = countdown
|
||||
LL| 1| ;
|
||||
LL| 1| countdown = 10
|
||||
LL| 1| ;
|
||||
LL| 1| }
|
||||
LL| | _
|
||||
LL| | =>
|
||||
LL| 1| {}
|
||||
LL| | }
|
||||
LL| | }
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,49 +1,49 @@
|
|||
1| |// compile-flags: --edition=2021
|
||||
2| |
|
||||
3| |// Demonstrate that `sort_subviews.py` can sort instantiation groups into a
|
||||
4| |// predictable order, while preserving their heterogeneous contents.
|
||||
5| |
|
||||
6| 1|fn main() {
|
||||
7| 1| let cond = std::env::args().len() > 1;
|
||||
8| 1| generic_fn::<()>(cond);
|
||||
9| 1| generic_fn::<&'static str>(!cond);
|
||||
10| 1| if false {
|
||||
11| 0| generic_fn::<char>(cond);
|
||||
12| 1| }
|
||||
13| 1| generic_fn::<i32>(cond);
|
||||
14| 1| other_fn();
|
||||
15| 1|}
|
||||
16| |
|
||||
17| 3|fn generic_fn<T>(cond: bool) {
|
||||
18| 3| if cond {
|
||||
19| 1| println!("{}", std::any::type_name::<T>());
|
||||
20| 2| }
|
||||
21| 3|}
|
||||
LL| |// compile-flags: --edition=2021
|
||||
LL| |
|
||||
LL| |// Demonstrate that `sort_subviews.py` can sort instantiation groups into a
|
||||
LL| |// predictable order, while preserving their heterogeneous contents.
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| let cond = std::env::args().len() > 1;
|
||||
LL| 1| generic_fn::<()>(cond);
|
||||
LL| 1| generic_fn::<&'static str>(!cond);
|
||||
LL| 1| if false {
|
||||
LL| 0| generic_fn::<char>(cond);
|
||||
LL| 1| }
|
||||
LL| 1| generic_fn::<i32>(cond);
|
||||
LL| 1| other_fn();
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| 3|fn generic_fn<T>(cond: bool) {
|
||||
LL| 3| if cond {
|
||||
LL| 1| println!("{}", std::any::type_name::<T>());
|
||||
LL| 2| }
|
||||
LL| 3|}
|
||||
------------------
|
||||
| Unexecuted instantiation: sort_groups::generic_fn::<char>
|
||||
------------------
|
||||
| sort_groups::generic_fn::<&str>:
|
||||
| 17| 1|fn generic_fn<T>(cond: bool) {
|
||||
| 18| 1| if cond {
|
||||
| 19| 1| println!("{}", std::any::type_name::<T>());
|
||||
| 20| 1| }
|
||||
| LL| 1|fn generic_fn<T>(cond: bool) {
|
||||
| LL| 1| if cond {
|
||||
| LL| 1| println!("{}", std::any::type_name::<T>());
|
||||
| LL| 1| }
|
||||
| ^0
|
||||
| 21| 1|}
|
||||
| LL| 1|}
|
||||
------------------
|
||||
| sort_groups::generic_fn::<()>:
|
||||
| 17| 1|fn generic_fn<T>(cond: bool) {
|
||||
| 18| 1| if cond {
|
||||
| 19| 0| println!("{}", std::any::type_name::<T>());
|
||||
| 20| 1| }
|
||||
| 21| 1|}
|
||||
| LL| 1|fn generic_fn<T>(cond: bool) {
|
||||
| LL| 1| if cond {
|
||||
| LL| 0| println!("{}", std::any::type_name::<T>());
|
||||
| LL| 1| }
|
||||
| LL| 1|}
|
||||
------------------
|
||||
| sort_groups::generic_fn::<i32>:
|
||||
| 17| 1|fn generic_fn<T>(cond: bool) {
|
||||
| 18| 1| if cond {
|
||||
| 19| 0| println!("{}", std::any::type_name::<T>());
|
||||
| 20| 1| }
|
||||
| 21| 1|}
|
||||
| LL| 1|fn generic_fn<T>(cond: bool) {
|
||||
| LL| 1| if cond {
|
||||
| LL| 0| println!("{}", std::any::type_name::<T>());
|
||||
| LL| 1| }
|
||||
| LL| 1|}
|
||||
------------------
|
||||
22| |
|
||||
23| 1|fn other_fn() {}
|
||||
LL| |
|
||||
LL| 1|fn other_fn() {}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
1| |// Verify that the entry point injected by the test harness doesn't cause
|
||||
2| |// weird artifacts in the coverage report (e.g. issue #10749).
|
||||
3| |
|
||||
4| |// compile-flags: --test
|
||||
5| |
|
||||
6| |#[allow(dead_code)]
|
||||
7| 0|fn unused() {}
|
||||
8| |
|
||||
9| 1|#[test]
|
||||
10| 1|fn my_test() {}
|
||||
LL| |// Verify that the entry point injected by the test harness doesn't cause
|
||||
LL| |// weird artifacts in the coverage report (e.g. issue #10749).
|
||||
LL| |
|
||||
LL| |// compile-flags: --test
|
||||
LL| |
|
||||
LL| |#[allow(dead_code)]
|
||||
LL| 0|fn unused() {}
|
||||
LL| |
|
||||
LL| 1|#[test]
|
||||
LL| 1|fn my_test() {}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
1| 1|fn main() {
|
||||
2| 1| if false {
|
||||
3| 0| loop {}
|
||||
4| 1| }
|
||||
5| 1|}
|
||||
LL| 1|fn main() {
|
||||
LL| 1| if false {
|
||||
LL| 0| loop {}
|
||||
LL| 1| }
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,125 +1,125 @@
|
|||
1| |#![allow(unused_assignments)]
|
||||
2| |// failure-status: 1
|
||||
3| |
|
||||
4| 6|fn call(return_error: bool) -> Result<(),()> {
|
||||
5| 6| if return_error {
|
||||
6| 1| Err(())
|
||||
7| | } else {
|
||||
8| 5| Ok(())
|
||||
9| | }
|
||||
10| 6|}
|
||||
11| |
|
||||
12| 1|fn test1() -> Result<(),()> {
|
||||
13| 1| let mut
|
||||
14| 1| countdown = 10
|
||||
15| | ;
|
||||
16| | for
|
||||
17| | _
|
||||
18| | in
|
||||
19| 6| 0..10
|
||||
20| | {
|
||||
21| 6| countdown
|
||||
22| 6| -= 1
|
||||
23| 6| ;
|
||||
24| 6| if
|
||||
25| 6| countdown < 5
|
||||
26| | {
|
||||
27| 1| call(/*return_error=*/ true)?;
|
||||
28| 0| call(/*return_error=*/ false)?;
|
||||
29| | }
|
||||
30| | else
|
||||
31| | {
|
||||
32| 5| call(/*return_error=*/ false)?;
|
||||
LL| |#![allow(unused_assignments)]
|
||||
LL| |// failure-status: 1
|
||||
LL| |
|
||||
LL| 6|fn call(return_error: bool) -> Result<(),()> {
|
||||
LL| 6| if return_error {
|
||||
LL| 1| Err(())
|
||||
LL| | } else {
|
||||
LL| 5| Ok(())
|
||||
LL| | }
|
||||
LL| 6|}
|
||||
LL| |
|
||||
LL| 1|fn test1() -> Result<(),()> {
|
||||
LL| 1| let mut
|
||||
LL| 1| countdown = 10
|
||||
LL| | ;
|
||||
LL| | for
|
||||
LL| | _
|
||||
LL| | in
|
||||
LL| 6| 0..10
|
||||
LL| | {
|
||||
LL| 6| countdown
|
||||
LL| 6| -= 1
|
||||
LL| 6| ;
|
||||
LL| 6| if
|
||||
LL| 6| countdown < 5
|
||||
LL| | {
|
||||
LL| 1| call(/*return_error=*/ true)?;
|
||||
LL| 0| call(/*return_error=*/ false)?;
|
||||
LL| | }
|
||||
LL| | else
|
||||
LL| | {
|
||||
LL| 5| call(/*return_error=*/ false)?;
|
||||
^0
|
||||
33| | }
|
||||
34| | }
|
||||
35| 0| Ok(())
|
||||
36| 1|}
|
||||
37| |
|
||||
38| |struct Thing1;
|
||||
39| |impl Thing1 {
|
||||
40| 18| fn get_thing_2(&self, return_error: bool) -> Result<Thing2,()> {
|
||||
41| 18| if return_error {
|
||||
42| 1| Err(())
|
||||
43| | } else {
|
||||
44| 17| Ok(Thing2{})
|
||||
45| | }
|
||||
46| 18| }
|
||||
47| |}
|
||||
48| |
|
||||
49| |struct Thing2;
|
||||
50| |impl Thing2 {
|
||||
51| 17| fn call(&self, return_error: bool) -> Result<u32,()> {
|
||||
52| 17| if return_error {
|
||||
53| 2| Err(())
|
||||
54| | } else {
|
||||
55| 15| Ok(57)
|
||||
56| | }
|
||||
57| 17| }
|
||||
58| |}
|
||||
59| |
|
||||
60| 1|fn test2() -> Result<(),()> {
|
||||
61| 1| let thing1 = Thing1{};
|
||||
62| 1| let mut
|
||||
63| 1| countdown = 10
|
||||
64| | ;
|
||||
65| | for
|
||||
66| | _
|
||||
67| | in
|
||||
68| 6| 0..10
|
||||
69| | {
|
||||
70| 6| countdown
|
||||
71| 6| -= 1
|
||||
72| 6| ;
|
||||
73| 6| if
|
||||
74| 6| countdown < 5
|
||||
75| | {
|
||||
76| 1| thing1.get_thing_2(/*err=*/ false)?.call(/*err=*/ true).expect_err("call should fail");
|
||||
LL| | }
|
||||
LL| | }
|
||||
LL| 0| Ok(())
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| |struct Thing1;
|
||||
LL| |impl Thing1 {
|
||||
LL| 18| fn get_thing_2(&self, return_error: bool) -> Result<Thing2,()> {
|
||||
LL| 18| if return_error {
|
||||
LL| 1| Err(())
|
||||
LL| | } else {
|
||||
LL| 17| Ok(Thing2{})
|
||||
LL| | }
|
||||
LL| 18| }
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| |struct Thing2;
|
||||
LL| |impl Thing2 {
|
||||
LL| 17| fn call(&self, return_error: bool) -> Result<u32,()> {
|
||||
LL| 17| if return_error {
|
||||
LL| 2| Err(())
|
||||
LL| | } else {
|
||||
LL| 15| Ok(57)
|
||||
LL| | }
|
||||
LL| 17| }
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| 1|fn test2() -> Result<(),()> {
|
||||
LL| 1| let thing1 = Thing1{};
|
||||
LL| 1| let mut
|
||||
LL| 1| countdown = 10
|
||||
LL| | ;
|
||||
LL| | for
|
||||
LL| | _
|
||||
LL| | in
|
||||
LL| 6| 0..10
|
||||
LL| | {
|
||||
LL| 6| countdown
|
||||
LL| 6| -= 1
|
||||
LL| 6| ;
|
||||
LL| 6| if
|
||||
LL| 6| countdown < 5
|
||||
LL| | {
|
||||
LL| 1| thing1.get_thing_2(/*err=*/ false)?.call(/*err=*/ true).expect_err("call should fail");
|
||||
^0
|
||||
77| 1| thing1
|
||||
78| 1| .
|
||||
79| 1| get_thing_2(/*return_error=*/ false)
|
||||
80| 0| ?
|
||||
81| | .
|
||||
82| 1| call(/*return_error=*/ true)
|
||||
83| 1| .
|
||||
84| 1| expect_err(
|
||||
85| 1| "call should fail"
|
||||
86| 1| );
|
||||
87| 1| let val = thing1.get_thing_2(/*return_error=*/ true)?.call(/*return_error=*/ true)?;
|
||||
LL| 1| thing1
|
||||
LL| 1| .
|
||||
LL| 1| get_thing_2(/*return_error=*/ false)
|
||||
LL| 0| ?
|
||||
LL| | .
|
||||
LL| 1| call(/*return_error=*/ true)
|
||||
LL| 1| .
|
||||
LL| 1| expect_err(
|
||||
LL| 1| "call should fail"
|
||||
LL| 1| );
|
||||
LL| 1| let val = thing1.get_thing_2(/*return_error=*/ true)?.call(/*return_error=*/ true)?;
|
||||
^0 ^0 ^0
|
||||
88| 0| assert_eq!(val, 57);
|
||||
89| 0| let val = thing1.get_thing_2(/*return_error=*/ true)?.call(/*return_error=*/ false)?;
|
||||
90| 0| assert_eq!(val, 57);
|
||||
91| | }
|
||||
92| | else
|
||||
93| | {
|
||||
94| 5| let val = thing1.get_thing_2(/*return_error=*/ false)?.call(/*return_error=*/ false)?;
|
||||
LL| 0| assert_eq!(val, 57);
|
||||
LL| 0| let val = thing1.get_thing_2(/*return_error=*/ true)?.call(/*return_error=*/ false)?;
|
||||
LL| 0| assert_eq!(val, 57);
|
||||
LL| | }
|
||||
LL| | else
|
||||
LL| | {
|
||||
LL| 5| let val = thing1.get_thing_2(/*return_error=*/ false)?.call(/*return_error=*/ false)?;
|
||||
^0 ^0
|
||||
95| 5| assert_eq!(val, 57);
|
||||
96| 5| let val = thing1
|
||||
97| 5| .get_thing_2(/*return_error=*/ false)?
|
||||
LL| 5| assert_eq!(val, 57);
|
||||
LL| 5| let val = thing1
|
||||
LL| 5| .get_thing_2(/*return_error=*/ false)?
|
||||
^0
|
||||
98| 5| .call(/*return_error=*/ false)?;
|
||||
LL| 5| .call(/*return_error=*/ false)?;
|
||||
^0
|
||||
99| 5| assert_eq!(val, 57);
|
||||
100| 5| let val = thing1
|
||||
101| 5| .get_thing_2(/*return_error=*/ false)
|
||||
102| 0| ?
|
||||
103| 5| .call(/*return_error=*/ false)
|
||||
104| 0| ?
|
||||
105| | ;
|
||||
106| 5| assert_eq!(val, 57);
|
||||
107| | }
|
||||
108| | }
|
||||
109| 0| Ok(())
|
||||
110| 1|}
|
||||
111| |
|
||||
112| 1|fn main() -> Result<(),()> {
|
||||
113| 1| test1().expect_err("test1 should fail");
|
||||
114| 1| test2()
|
||||
115| 1| ?
|
||||
116| | ;
|
||||
117| 0| Ok(())
|
||||
118| 1|}
|
||||
LL| 5| assert_eq!(val, 57);
|
||||
LL| 5| let val = thing1
|
||||
LL| 5| .get_thing_2(/*return_error=*/ false)
|
||||
LL| 0| ?
|
||||
LL| 5| .call(/*return_error=*/ false)
|
||||
LL| 0| ?
|
||||
LL| | ;
|
||||
LL| 5| assert_eq!(val, 57);
|
||||
LL| | }
|
||||
LL| | }
|
||||
LL| 0| Ok(())
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| 1|fn main() -> Result<(),()> {
|
||||
LL| 1| test1().expect_err("test1 should fail");
|
||||
LL| 1| test2()
|
||||
LL| 1| ?
|
||||
LL| | ;
|
||||
LL| 0| Ok(())
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,62 +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;
|
||||
LL| 2|fn foo<T>(x: T) {
|
||||
LL| 2| let mut i = 0;
|
||||
LL| 22| while i < 10 {
|
||||
LL| 20| i != 0 || i != 0;
|
||||
^2
|
||||
5| 20| i += 1;
|
||||
6| | }
|
||||
7| 2|}
|
||||
LL| 20| i += 1;
|
||||
LL| | }
|
||||
LL| 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;
|
||||
| LL| 1|fn foo<T>(x: T) {
|
||||
| LL| 1| let mut i = 0;
|
||||
| LL| 11| while i < 10 {
|
||||
| LL| 10| i != 0 || i != 0;
|
||||
| ^1
|
||||
| 5| 10| i += 1;
|
||||
| 6| | }
|
||||
| 7| 1|}
|
||||
| LL| 10| i += 1;
|
||||
| LL| | }
|
||||
| LL| 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;
|
||||
| LL| 1|fn foo<T>(x: T) {
|
||||
| LL| 1| let mut i = 0;
|
||||
| LL| 11| while i < 10 {
|
||||
| LL| 10| i != 0 || i != 0;
|
||||
| ^1
|
||||
| 5| 10| i += 1;
|
||||
| 6| | }
|
||||
| 7| 1|}
|
||||
| LL| 10| i += 1;
|
||||
| LL| | }
|
||||
| LL| 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|}
|
||||
LL| |
|
||||
LL| 0|fn unused_template_func<T>(x: T) {
|
||||
LL| 0| let mut i = 0;
|
||||
LL| 0| while i < 10 {
|
||||
LL| 0| i != 0 || i != 0;
|
||||
LL| 0| i += 1;
|
||||
LL| | }
|
||||
LL| 0|}
|
||||
LL| |
|
||||
LL| 0|fn unused_func(mut a: u32) {
|
||||
LL| 0| if a != 0 {
|
||||
LL| 0| a += 1;
|
||||
LL| 0| }
|
||||
LL| 0|}
|
||||
LL| |
|
||||
LL| 0|fn unused_func2(mut a: u32) {
|
||||
LL| 0| if a != 0 {
|
||||
LL| 0| a += 1;
|
||||
LL| 0| }
|
||||
LL| 0|}
|
||||
LL| |
|
||||
LL| 0|fn unused_func3(mut a: u32) {
|
||||
LL| 0| if a != 0 {
|
||||
LL| 0| a += 1;
|
||||
LL| 0| }
|
||||
LL| 0|}
|
||||
LL| |
|
||||
LL| 1|fn main() -> Result<(), u8> {
|
||||
LL| 1| foo::<u32>(0);
|
||||
LL| 1| foo::<f32>(0.0);
|
||||
LL| 1| Ok(())
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
$DIR/auxiliary/unused_mod_helper.rs:
|
||||
1| 0|pub fn never_called_function() {
|
||||
2| 0| println!("I am never called");
|
||||
3| 0|}
|
||||
LL| 0|pub fn never_called_function() {
|
||||
LL| 0| println!("I am never called");
|
||||
LL| 0|}
|
||||
|
||||
$DIR/unused_mod.rs:
|
||||
1| |#[path = "auxiliary/unused_mod_helper.rs"]
|
||||
2| |mod unused_module;
|
||||
3| |
|
||||
4| 1|fn main() {
|
||||
5| 1| println!("hello world!");
|
||||
6| 1|}
|
||||
LL| |#[path = "auxiliary/unused_mod_helper.rs"]
|
||||
LL| |mod unused_module;
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| println!("hello world!");
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,170 +1,170 @@
|
|||
$DIR/auxiliary/used_crate.rs:
|
||||
1| |#![allow(unused_assignments, unused_variables)]
|
||||
2| |// compile-flags: -C opt-level=3
|
||||
3| |use std::fmt::Debug; // ^^ validates coverage now works with optimizations
|
||||
4| |
|
||||
5| 1|pub fn used_function() {
|
||||
6| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
7| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
8| 1| // 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| }
|
||||
LL| |#![allow(unused_assignments, unused_variables)]
|
||||
LL| |// compile-flags: -C opt-level=3
|
||||
LL| |use std::fmt::Debug; // ^^ validates coverage now works with optimizations
|
||||
LL| |
|
||||
LL| 1|pub fn used_function() {
|
||||
LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
LL| 1| // dependent conditions.
|
||||
LL| 1| let is_true = std::env::args().len() == 1;
|
||||
LL| 1| let mut countdown = 0;
|
||||
LL| 1| if is_true {
|
||||
LL| 1| countdown = 10;
|
||||
LL| 1| }
|
||||
^0
|
||||
14| 1| use_this_lib_crate();
|
||||
15| 1|}
|
||||
16| |
|
||||
17| 2|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
|
||||
18| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
|
||||
19| 2|}
|
||||
LL| 1| use_this_lib_crate();
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| 2|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
|
||||
LL| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
|
||||
LL| 2|}
|
||||
------------------
|
||||
| Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_>
|
||||
------------------
|
||||
| used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
|
||||
| 17| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
|
||||
| 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
|
||||
| 19| 1|}
|
||||
| LL| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
|
||||
| LL| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
|
||||
| LL| 1|}
|
||||
------------------
|
||||
| used_crate::used_only_from_bin_crate_generic_function::<&str>:
|
||||
| 17| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
|
||||
| 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
|
||||
| 19| 1|}
|
||||
| LL| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
|
||||
| LL| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
|
||||
| LL| 1|}
|
||||
------------------
|
||||
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|}
|
||||
LL| |// Expect for above function: `Unexecuted instantiation` (see below)
|
||||
LL| 2|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
|
||||
LL| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
|
||||
LL| 2|}
|
||||
------------------
|
||||
| used_crate::used_only_from_this_lib_crate_generic_function::<&str>:
|
||||
| 21| 1|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
|
||||
| 22| 1| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
|
||||
| 23| 1|}
|
||||
| LL| 1|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
|
||||
| LL| 1| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
|
||||
| LL| 1|}
|
||||
------------------
|
||||
| used_crate::used_only_from_this_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
|
||||
| 21| 1|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
|
||||
| 22| 1| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
|
||||
| 23| 1|}
|
||||
| LL| 1|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
|
||||
| LL| 1| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
|
||||
| LL| 1|}
|
||||
------------------
|
||||
24| |
|
||||
25| 2|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
|
||||
26| 2| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
|
||||
27| 2|}
|
||||
LL| |
|
||||
LL| 2|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
|
||||
LL| 2| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
|
||||
LL| 2|}
|
||||
------------------
|
||||
| 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<T: Debug>(arg: T) {
|
||||
| 26| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
|
||||
| 27| 1|}
|
||||
| LL| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
|
||||
| LL| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
|
||||
| LL| 1|}
|
||||
------------------
|
||||
| used_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
|
||||
| 25| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
|
||||
| 26| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
|
||||
| 27| 1|}
|
||||
| LL| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
|
||||
| LL| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
|
||||
| LL| 1|}
|
||||
------------------
|
||||
28| |
|
||||
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|}
|
||||
LL| |
|
||||
LL| 2|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
|
||||
LL| 2| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
|
||||
LL| 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|}
|
||||
| LL| 1|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
|
||||
| LL| 1| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
|
||||
| LL| 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|}
|
||||
| LL| 1|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
|
||||
| LL| 1| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
|
||||
| LL| 1|}
|
||||
------------------
|
||||
32| |
|
||||
33| 0|pub fn unused_generic_function<T: Debug>(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|}
|
||||
62| |
|
||||
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 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| |// ```shell
|
||||
81| |// $ `rustc -Zunstable-options -C 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.
|
||||
LL| |
|
||||
LL| 0|pub fn unused_generic_function<T: Debug>(arg: T) {
|
||||
LL| 0| println!("unused_generic_function with {:?}", arg);
|
||||
LL| 0|}
|
||||
LL| |
|
||||
LL| 0|pub fn unused_function() {
|
||||
LL| 0| let is_true = std::env::args().len() == 1;
|
||||
LL| 0| let mut countdown = 2;
|
||||
LL| 0| if !is_true {
|
||||
LL| 0| countdown = 20;
|
||||
LL| 0| }
|
||||
LL| 0|}
|
||||
LL| |
|
||||
LL| 0|fn unused_private_function() {
|
||||
LL| 0| let is_true = std::env::args().len() == 1;
|
||||
LL| 0| let mut countdown = 2;
|
||||
LL| 0| if !is_true {
|
||||
LL| 0| countdown = 20;
|
||||
LL| 0| }
|
||||
LL| 0|}
|
||||
LL| |
|
||||
LL| 1|fn use_this_lib_crate() {
|
||||
LL| 1| used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
|
||||
LL| 1| used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
|
||||
LL| 1| "used from library used_crate.rs",
|
||||
LL| 1| );
|
||||
LL| 1| let some_vec = vec![5, 6, 7, 8];
|
||||
LL| 1| used_only_from_this_lib_crate_generic_function(some_vec);
|
||||
LL| 1| used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| |// FIXME(#79651): "Unexecuted instantiation" errors appear in coverage results,
|
||||
LL| |// for example:
|
||||
LL| |//
|
||||
LL| |// | Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_>
|
||||
LL| |//
|
||||
LL| |// These notices appear when `llvm-cov` shows instantiations. This may be a
|
||||
LL| |// default option, but it can be suppressed with:
|
||||
LL| |//
|
||||
LL| |// ```shell
|
||||
LL| |// $ `llvm-cov show --show-instantiations=0 ...`
|
||||
LL| |// ```
|
||||
LL| |//
|
||||
LL| |// The notice is triggered because the function is unused by the library itself,
|
||||
LL| |// and when the library is compiled, a synthetic function is generated, so
|
||||
LL| |// unused function coverage can be reported. Coverage can be skipped for unused
|
||||
LL| |// generic functions with:
|
||||
LL| |//
|
||||
LL| |// ```shell
|
||||
LL| |// $ `rustc -Zunstable-options -C instrument-coverage=except-unused-generics ...`
|
||||
LL| |// ```
|
||||
LL| |//
|
||||
LL| |// Even though this function is used by `uses_crate.rs` (and
|
||||
LL| |// counted), with substitutions for `T`, those instantiations are only generated
|
||||
LL| |// when the generic function is actually used (from the binary, not from this
|
||||
LL| |// library crate). So the test result shows coverage for all instantiated
|
||||
LL| |// versions and their generic type substitutions, plus the `Unexecuted
|
||||
LL| |// instantiation` message for the non-substituted version. This is valid, but
|
||||
LL| |// unfortunately a little confusing.
|
||||
LL| |//
|
||||
LL| |// The library crate has its own coverage map, and the only way to show unused
|
||||
LL| |// coverage of a generic function is to include the generic function in the
|
||||
LL| |// coverage map, marked as an "unused function". If the library were used by
|
||||
LL| |// another binary that never used this generic function, then it would be valid
|
||||
LL| |// to show the unused generic, with unknown substitution (`_`).
|
||||
LL| |//
|
||||
LL| |// The alternative is to exclude all generics from being included in the "unused
|
||||
LL| |// functions" list, which would then omit coverage results for
|
||||
LL| |// `unused_generic_function<T>()`, below.
|
||||
|
||||
$DIR/uses_crate.rs:
|
||||
1| |// This test was failing on Linux for a while due to #110393 somehow making
|
||||
2| |// the unused functions not instrumented, but it seems to be fine now.
|
||||
3| |
|
||||
4| |// Validates coverage now works with optimizations
|
||||
5| |// compile-flags: -C opt-level=3
|
||||
6| |
|
||||
7| |#![allow(unused_assignments, unused_variables)]
|
||||
8| |
|
||||
9| |// aux-build:used_crate.rs
|
||||
10| |extern crate used_crate;
|
||||
11| |
|
||||
12| 1|fn main() {
|
||||
13| 1| used_crate::used_function();
|
||||
14| 1| let some_vec = vec![1, 2, 3, 4];
|
||||
15| 1| used_crate::used_only_from_bin_crate_generic_function(&some_vec);
|
||||
16| 1| used_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");
|
||||
17| 1| used_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);
|
||||
18| 1| used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function("interesting?");
|
||||
19| 1|}
|
||||
LL| |// This test was failing on Linux for a while due to #110393 somehow making
|
||||
LL| |// the unused functions not instrumented, but it seems to be fine now.
|
||||
LL| |
|
||||
LL| |// Validates coverage now works with optimizations
|
||||
LL| |// compile-flags: -C opt-level=3
|
||||
LL| |
|
||||
LL| |#![allow(unused_assignments, unused_variables)]
|
||||
LL| |
|
||||
LL| |// aux-build:used_crate.rs
|
||||
LL| |extern crate used_crate;
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| used_crate::used_function();
|
||||
LL| 1| let some_vec = vec![1, 2, 3, 4];
|
||||
LL| 1| used_crate::used_only_from_bin_crate_generic_function(&some_vec);
|
||||
LL| 1| used_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");
|
||||
LL| 1| used_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);
|
||||
LL| 1| used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function("interesting?");
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,164 +1,164 @@
|
|||
$DIR/auxiliary/used_inline_crate.rs:
|
||||
1| |#![allow(unused_assignments, unused_variables)]
|
||||
2| |
|
||||
3| |// compile-flags: -C opt-level=3
|
||||
4| |// ^^ validates coverage now works with optimizations
|
||||
5| |use std::fmt::Debug;
|
||||
6| |
|
||||
7| 1|pub fn used_function() {
|
||||
8| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
9| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
10| 1| // 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| }
|
||||
LL| |#![allow(unused_assignments, unused_variables)]
|
||||
LL| |
|
||||
LL| |// compile-flags: -C opt-level=3
|
||||
LL| |// ^^ validates coverage now works with optimizations
|
||||
LL| |use std::fmt::Debug;
|
||||
LL| |
|
||||
LL| 1|pub fn used_function() {
|
||||
LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
LL| 1| // dependent conditions.
|
||||
LL| 1| let is_true = std::env::args().len() == 1;
|
||||
LL| 1| let mut countdown = 0;
|
||||
LL| 1| if is_true {
|
||||
LL| 1| countdown = 10;
|
||||
LL| 1| }
|
||||
^0
|
||||
16| 1| use_this_lib_crate();
|
||||
17| 1|}
|
||||
18| |
|
||||
19| |#[inline(always)]
|
||||
20| 1|pub fn used_inline_function() {
|
||||
21| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
22| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
23| 1| // 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| }
|
||||
LL| 1| use_this_lib_crate();
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| |#[inline(always)]
|
||||
LL| 1|pub fn used_inline_function() {
|
||||
LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
|
||||
LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
|
||||
LL| 1| // dependent conditions.
|
||||
LL| 1| let is_true = std::env::args().len() == 1;
|
||||
LL| 1| let mut countdown = 0;
|
||||
LL| 1| if is_true {
|
||||
LL| 1| countdown = 10;
|
||||
LL| 1| }
|
||||
^0
|
||||
29| 1| use_this_lib_crate();
|
||||
30| 1|}
|
||||
31| |
|
||||
32| |
|
||||
33| |
|
||||
34| |
|
||||
35| |
|
||||
36| |
|
||||
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|}
|
||||
LL| 1| use_this_lib_crate();
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| |
|
||||
LL| |
|
||||
LL| |
|
||||
LL| |
|
||||
LL| |
|
||||
LL| |
|
||||
LL| |#[inline(always)]
|
||||
LL| 2|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
|
||||
LL| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
|
||||
LL| 2|}
|
||||
------------------
|
||||
| Unexecuted instantiation: used_inline_crate::used_only_from_bin_crate_generic_function::<_>
|
||||
------------------
|
||||
| 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|}
|
||||
| LL| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
|
||||
| LL| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
|
||||
| LL| 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|}
|
||||
| LL| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
|
||||
| LL| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
|
||||
| LL| 1|}
|
||||
------------------
|
||||
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|}
|
||||
LL| |// Expect for above function: `Unexecuted instantiation` (see notes in `used_crate.rs`)
|
||||
LL| |
|
||||
LL| |#[inline(always)]
|
||||
LL| 4|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
|
||||
LL| 4| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
|
||||
LL| 4|}
|
||||
------------------
|
||||
| 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|}
|
||||
| LL| 2|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
|
||||
| LL| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
|
||||
| LL| 2|}
|
||||
------------------
|
||||
| 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|}
|
||||
| LL| 2|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
|
||||
| LL| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
|
||||
| LL| 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|}
|
||||
LL| |
|
||||
LL| |#[inline(always)]
|
||||
LL| 3|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
|
||||
LL| 3| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
|
||||
LL| 3|}
|
||||
------------------
|
||||
| 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|}
|
||||
| LL| 2|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
|
||||
| LL| 2| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
|
||||
| LL| 2|}
|
||||
------------------
|
||||
| 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|}
|
||||
| LL| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
|
||||
| LL| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
|
||||
| LL| 1|}
|
||||
------------------
|
||||
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|}
|
||||
LL| |
|
||||
LL| |#[inline(always)]
|
||||
LL| 3|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
|
||||
LL| 3| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
|
||||
LL| 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|}
|
||||
| LL| 1|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
|
||||
| LL| 1| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
|
||||
| LL| 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|}
|
||||
| LL| 2|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
|
||||
| LL| 2| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
|
||||
| LL| 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|}
|
||||
LL| |
|
||||
LL| |#[inline(always)]
|
||||
LL| 0|pub fn unused_generic_function<T: Debug>(arg: T) {
|
||||
LL| 0| println!("unused_generic_function with {:?}", arg);
|
||||
LL| 0|}
|
||||
LL| |
|
||||
LL| |#[inline(always)]
|
||||
LL| 0|pub fn unused_function() {
|
||||
LL| 0| let is_true = std::env::args().len() == 1;
|
||||
LL| 0| let mut countdown = 2;
|
||||
LL| 0| if !is_true {
|
||||
LL| 0| countdown = 20;
|
||||
LL| 0| }
|
||||
LL| 0|}
|
||||
LL| |
|
||||
LL| |#[inline(always)]
|
||||
LL| 0|fn unused_private_function() {
|
||||
LL| 0| let is_true = std::env::args().len() == 1;
|
||||
LL| 0| let mut countdown = 2;
|
||||
LL| 0| if !is_true {
|
||||
LL| 0| countdown = 20;
|
||||
LL| 0| }
|
||||
LL| 0|}
|
||||
LL| |
|
||||
LL| 2|fn use_this_lib_crate() {
|
||||
LL| 2| used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
|
||||
LL| 2| used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
|
||||
LL| 2| "used from library used_crate.rs",
|
||||
LL| 2| );
|
||||
LL| 2| let some_vec = vec![5, 6, 7, 8];
|
||||
LL| 2| used_only_from_this_lib_crate_generic_function(some_vec);
|
||||
LL| 2| used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
|
||||
LL| 2|}
|
||||
|
||||
$DIR/uses_inline_crate.rs:
|
||||
1| |// This test was failing on Linux for a while due to #110393 somehow making
|
||||
2| |// the unused functions not instrumented, but it seems to be fine now.
|
||||
3| |
|
||||
4| |// Validates coverage now works with optimizations
|
||||
5| |// compile-flags: -C opt-level=3
|
||||
6| |
|
||||
7| |#![allow(unused_assignments, unused_variables)]
|
||||
8| |
|
||||
9| |// aux-build:used_inline_crate.rs
|
||||
10| |extern crate used_inline_crate;
|
||||
11| |
|
||||
12| 1|fn main() {
|
||||
13| 1| used_inline_crate::used_function();
|
||||
14| 1| used_inline_crate::used_inline_function();
|
||||
15| 1| let some_vec = vec![1, 2, 3, 4];
|
||||
16| 1| used_inline_crate::used_only_from_bin_crate_generic_function(&some_vec);
|
||||
17| 1| used_inline_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");
|
||||
18| 1| used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);
|
||||
19| 1| used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
|
||||
20| 1| "interesting?",
|
||||
21| 1| );
|
||||
22| 1|}
|
||||
LL| |// This test was failing on Linux for a while due to #110393 somehow making
|
||||
LL| |// the unused functions not instrumented, but it seems to be fine now.
|
||||
LL| |
|
||||
LL| |// Validates coverage now works with optimizations
|
||||
LL| |// compile-flags: -C opt-level=3
|
||||
LL| |
|
||||
LL| |#![allow(unused_assignments, unused_variables)]
|
||||
LL| |
|
||||
LL| |// aux-build:used_inline_crate.rs
|
||||
LL| |extern crate used_inline_crate;
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| used_inline_crate::used_function();
|
||||
LL| 1| used_inline_crate::used_inline_function();
|
||||
LL| 1| let some_vec = vec![1, 2, 3, 4];
|
||||
LL| 1| used_inline_crate::used_only_from_bin_crate_generic_function(&some_vec);
|
||||
LL| 1| used_inline_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");
|
||||
LL| 1| used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);
|
||||
LL| 1| used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
|
||||
LL| 1| "interesting?",
|
||||
LL| 1| );
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
1| 1|fn main() {
|
||||
2| 1| let num = 9;
|
||||
3| 1| while num >= 10 {
|
||||
4| 0| }
|
||||
5| 1|}
|
||||
LL| 1|fn main() {
|
||||
LL| 1| let num = 9;
|
||||
LL| 1| while num >= 10 {
|
||||
LL| 0| }
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -1,43 +1,43 @@
|
|||
1| |#![allow(unused_assignments)]
|
||||
2| |// failure-status: 1
|
||||
3| |
|
||||
4| 1|fn main() -> Result<(),u8> {
|
||||
5| 1| let mut countdown = 10;
|
||||
6| | while
|
||||
7| 7| countdown
|
||||
8| 7| >
|
||||
9| 7| 0
|
||||
10| | {
|
||||
11| | if
|
||||
12| 7| countdown
|
||||
13| 7| <
|
||||
14| 7| 5
|
||||
15| | {
|
||||
16| | return
|
||||
17| | if
|
||||
18| 1| countdown
|
||||
19| 1| >
|
||||
20| 1| 8
|
||||
21| | {
|
||||
22| 0| Ok(())
|
||||
23| | }
|
||||
24| | else
|
||||
25| | {
|
||||
26| 1| Err(1)
|
||||
27| | }
|
||||
28| | ;
|
||||
29| 6| }
|
||||
30| 6| countdown
|
||||
31| 6| -=
|
||||
32| 6| 1
|
||||
33| | ;
|
||||
34| | }
|
||||
35| 0| Ok(())
|
||||
36| 1|}
|
||||
37| |
|
||||
38| |// ISSUE(77553): Originally, this test had `Err(1)` on line 22 (instead of `Ok(())`) and
|
||||
39| |// `std::process::exit(2)` on line 26 (instead of `Err(1)`); and this worked as expected on Linux
|
||||
40| |// and MacOS. But on Windows (MSVC, at least), the call to `std::process::exit()` exits the program
|
||||
41| |// without saving the InstrProf coverage counters. The use of `std::process:exit()` is not critical
|
||||
42| |// to the coverage test for early returns, but this is a limitation that should be fixed.
|
||||
LL| |#![allow(unused_assignments)]
|
||||
LL| |// failure-status: 1
|
||||
LL| |
|
||||
LL| 1|fn main() -> Result<(),u8> {
|
||||
LL| 1| let mut countdown = 10;
|
||||
LL| | while
|
||||
LL| 7| countdown
|
||||
LL| 7| >
|
||||
LL| 7| 0
|
||||
LL| | {
|
||||
LL| | if
|
||||
LL| 7| countdown
|
||||
LL| 7| <
|
||||
LL| 7| 5
|
||||
LL| | {
|
||||
LL| | return
|
||||
LL| | if
|
||||
LL| 1| countdown
|
||||
LL| 1| >
|
||||
LL| 1| 8
|
||||
LL| | {
|
||||
LL| 0| Ok(())
|
||||
LL| | }
|
||||
LL| | else
|
||||
LL| | {
|
||||
LL| 1| Err(1)
|
||||
LL| | }
|
||||
LL| | ;
|
||||
LL| 6| }
|
||||
LL| 6| countdown
|
||||
LL| 6| -=
|
||||
LL| 6| 1
|
||||
LL| | ;
|
||||
LL| | }
|
||||
LL| 0| Ok(())
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| |// ISSUE(77553): Originally, this test had `Err(1)` on line 22 (instead of `Ok(())`) and
|
||||
LL| |// `std::process::exit(2)` on line 26 (instead of `Err(1)`); and this worked as expected on Linux
|
||||
LL| |// and MacOS. But on Windows (MSVC, at least), the call to `std::process::exit()` exits the program
|
||||
LL| |// without saving the InstrProf coverage counters. The use of `std::process:exit()` is not critical
|
||||
LL| |// to the coverage test for early returns, but this is a limitation that should be fixed.
|
||||
|
||||
|
|
|
@ -1,38 +1,38 @@
|
|||
1| |#![feature(generators, generator_trait)]
|
||||
2| |#![allow(unused_assignments)]
|
||||
3| |
|
||||
4| |use std::ops::{Generator, GeneratorState};
|
||||
5| |use std::pin::Pin;
|
||||
6| |
|
||||
7| 1|fn main() {
|
||||
8| 1| let mut generator = || {
|
||||
9| 1| yield 1;
|
||||
10| 1| return "foo"
|
||||
11| 1| };
|
||||
12| |
|
||||
13| 1| match Pin::new(&mut generator).resume(()) {
|
||||
14| 1| GeneratorState::Yielded(1) => {}
|
||||
15| 0| _ => panic!("unexpected value from resume"),
|
||||
16| | }
|
||||
17| 1| match Pin::new(&mut generator).resume(()) {
|
||||
18| 1| GeneratorState::Complete("foo") => {}
|
||||
19| 0| _ => panic!("unexpected value from resume"),
|
||||
20| | }
|
||||
21| |
|
||||
22| 1| let mut generator = || {
|
||||
23| 1| yield 1;
|
||||
24| 1| yield 2;
|
||||
25| 0| yield 3;
|
||||
26| 0| return "foo"
|
||||
27| 0| };
|
||||
28| |
|
||||
29| 1| match Pin::new(&mut generator).resume(()) {
|
||||
30| 1| GeneratorState::Yielded(1) => {}
|
||||
31| 0| _ => panic!("unexpected value from resume"),
|
||||
32| | }
|
||||
33| 1| match Pin::new(&mut generator).resume(()) {
|
||||
34| 1| GeneratorState::Yielded(2) => {}
|
||||
35| 0| _ => panic!("unexpected value from resume"),
|
||||
36| | }
|
||||
37| 1|}
|
||||
LL| |#![feature(generators, generator_trait)]
|
||||
LL| |#![allow(unused_assignments)]
|
||||
LL| |
|
||||
LL| |use std::ops::{Generator, GeneratorState};
|
||||
LL| |use std::pin::Pin;
|
||||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| let mut generator = || {
|
||||
LL| 1| yield 1;
|
||||
LL| 1| return "foo"
|
||||
LL| 1| };
|
||||
LL| |
|
||||
LL| 1| match Pin::new(&mut generator).resume(()) {
|
||||
LL| 1| GeneratorState::Yielded(1) => {}
|
||||
LL| 0| _ => panic!("unexpected value from resume"),
|
||||
LL| | }
|
||||
LL| 1| match Pin::new(&mut generator).resume(()) {
|
||||
LL| 1| GeneratorState::Complete("foo") => {}
|
||||
LL| 0| _ => panic!("unexpected value from resume"),
|
||||
LL| | }
|
||||
LL| |
|
||||
LL| 1| let mut generator = || {
|
||||
LL| 1| yield 1;
|
||||
LL| 1| yield 2;
|
||||
LL| 0| yield 3;
|
||||
LL| 0| return "foo"
|
||||
LL| 0| };
|
||||
LL| |
|
||||
LL| 1| match Pin::new(&mut generator).resume(()) {
|
||||
LL| 1| GeneratorState::Yielded(1) => {}
|
||||
LL| 0| _ => panic!("unexpected value from resume"),
|
||||
LL| | }
|
||||
LL| 1| match Pin::new(&mut generator).resume(()) {
|
||||
LL| 1| GeneratorState::Yielded(2) => {}
|
||||
LL| 0| _ => panic!("unexpected value from resume"),
|
||||
LL| | }
|
||||
LL| 1|}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue