Skip to content

Commit d51d710

Browse files
committed
Auto merge of rust-lang#119681 - Zalathar:anon-branch, r=clubby789
coverage: Anonymize line numbers in branch views Extracted from rust-lang#118305, as this is now the only part of that PR that needs to touch compiletest. --- Coverage tests run the `llvm-cov` tool to generate a coverage report for a test program, and then compare the report against a known-good snapshot. We use the `anonymize_coverage_line_numbers` function to replace line numbers in coverage reports with `LL`, so that they are less sensitive to lines being added or removed. This PR augments the existing code by making it also support the slightly different line number syntax used when reporting branch regions. Currently the compiler never emits branch regions, so there is no way to write a coverage test that makes use of this new capability. Instead, I've added a unit test that checks against some sample reports taken from rust-lang#118305. That unit test can be removed when some form of branch coverage support gets merged, and real branch coverage tests are added to the coverage test suite. (I have also manually tested this change as part of my draft branch-coverage PR.)
2 parents d8b44d2 + 957a46f commit d51d710

File tree

2 files changed

+93
-3
lines changed

2 files changed

+93
-3
lines changed

src/tools/compiletest/src/runtest.rs

+21-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use miropt_test_tools::{files_for_miropt_test, MiroptTest, MiroptTestFile};
1919
use regex::{Captures, Regex};
2020
use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
2121

22-
use std::borrow::Cow;
2322
use std::collections::{HashMap, HashSet};
2423
use std::env;
2524
use std::ffi::{OsStr, OsString};
@@ -725,17 +724,36 @@ impl<'test> TestCx<'test> {
725724

726725
/// Replace line numbers in coverage reports with the placeholder `LL`,
727726
/// so that the tests are less sensitive to lines being added/removed.
728-
fn anonymize_coverage_line_numbers(coverage: &str) -> Cow<'_, str> {
727+
fn anonymize_coverage_line_numbers(coverage: &str) -> String {
729728
// The coverage reporter prints line numbers at the start of a line.
730729
// They are truncated or left-padded to occupy exactly 5 columns.
731730
// (`LineNumberColumnWidth` in `SourceCoverageViewText.cpp`.)
732731
// A pipe character `|` appears immediately after the final digit.
733732
//
734733
// Line numbers that appear inside expansion/instantiation subviews
735734
// have an additional prefix of ` |` for each nesting level.
735+
//
736+
// Branch views also include the relevant line number, so we want to
737+
// redact those too. (These line numbers don't have padding.)
738+
//
739+
// Note: The pattern `(?m:^)` matches the start of a line.
740+
741+
// ` 1|` => ` LL|`
742+
// ` 10|` => ` LL|`
743+
// ` 100|` => ` LL|`
744+
// ` | 1000|` => ` | LL|`
745+
// ` | | 1000|` => ` | | LL|`
736746
static LINE_NUMBER_RE: Lazy<Regex> =
737747
Lazy::new(|| Regex::new(r"(?m:^)(?<prefix>(?: \|)*) *[0-9]+\|").unwrap());
738-
LINE_NUMBER_RE.replace_all(coverage, "$prefix LL|")
748+
let coverage = LINE_NUMBER_RE.replace_all(&coverage, "${prefix} LL|");
749+
750+
// ` | Branch (1:` => ` | Branch (LL:`
751+
// ` | | Branch (10:` => ` | | Branch (LL:`
752+
static BRANCH_LINE_NUMBER_RE: Lazy<Regex> =
753+
Lazy::new(|| Regex::new(r"(?m:^)(?<prefix>(?: \|)+ Branch \()[0-9]+:").unwrap());
754+
let coverage = BRANCH_LINE_NUMBER_RE.replace_all(&coverage, "${prefix}LL:");
755+
756+
coverage.into_owned()
739757
}
740758

741759
/// Coverage reports can describe multiple source files, separated by

src/tools/compiletest/src/runtest/tests.rs

+72
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,75 @@ fn normalize_platform_differences() {
4848
r#"println!("test\ntest")"#,
4949
);
5050
}
51+
52+
/// Test for anonymizing line numbers in coverage reports, especially for
53+
/// branch regions.
54+
///
55+
/// FIXME(#119681): This test can be removed when we have examples of branch
56+
/// coverage in the actual coverage test suite.
57+
#[test]
58+
fn anonymize_coverage_line_numbers() {
59+
let anon = |coverage| TestCx::anonymize_coverage_line_numbers(coverage);
60+
61+
let input = r#"
62+
6| 3|fn print_size<T>() {
63+
7| 3| if std::mem::size_of::<T>() > 4 {
64+
------------------
65+
| Branch (7:8): [True: 0, False: 1]
66+
| Branch (7:8): [True: 0, False: 1]
67+
| Branch (7:8): [True: 1, False: 0]
68+
------------------
69+
8| 1| println!("size > 4");
70+
"#;
71+
72+
let expected = r#"
73+
LL| 3|fn print_size<T>() {
74+
LL| 3| if std::mem::size_of::<T>() > 4 {
75+
------------------
76+
| Branch (LL:8): [True: 0, False: 1]
77+
| Branch (LL:8): [True: 0, False: 1]
78+
| Branch (LL:8): [True: 1, False: 0]
79+
------------------
80+
LL| 1| println!("size > 4");
81+
"#;
82+
83+
assert_eq!(anon(input), expected);
84+
85+
//////////
86+
87+
let input = r#"
88+
12| 3|}
89+
------------------
90+
| branch_generics::print_size::<()>:
91+
| 6| 1|fn print_size<T>() {
92+
| 7| 1| if std::mem::size_of::<T>() > 4 {
93+
| ------------------
94+
| | Branch (7:8): [True: 0, False: 1]
95+
| ------------------
96+
| 8| 0| println!("size > 4");
97+
| 9| 1| } else {
98+
| 10| 1| println!("size <= 4");
99+
| 11| 1| }
100+
| 12| 1|}
101+
------------------
102+
"#;
103+
104+
let expected = r#"
105+
LL| 3|}
106+
------------------
107+
| branch_generics::print_size::<()>:
108+
| LL| 1|fn print_size<T>() {
109+
| LL| 1| if std::mem::size_of::<T>() > 4 {
110+
| ------------------
111+
| | Branch (LL:8): [True: 0, False: 1]
112+
| ------------------
113+
| LL| 0| println!("size > 4");
114+
| LL| 1| } else {
115+
| LL| 1| println!("size <= 4");
116+
| LL| 1| }
117+
| LL| 1|}
118+
------------------
119+
"#;
120+
121+
assert_eq!(anon(input), expected);
122+
}

0 commit comments

Comments
 (0)