about summary refs log tree commit diff
diff options
context:
space:
mode:
authorZalathar <Zalathar@users.noreply.github.com>2023-11-16 12:32:51 +1100
committerZalathar <Zalathar@users.noreply.github.com>2024-01-07 21:14:55 +1100
commit957a46fa69db5a67fad317305213b51d27e9df6e (patch)
tree9e59c7a036f9bc70731481edfe30c406b882dba4
parent6f4af9cbfc5ec176359c85446d1259a988299ea0 (diff)
downloadrust-957a46fa69db5a67fad317305213b51d27e9df6e.tar.gz
rust-957a46fa69db5a67fad317305213b51d27e9df6e.zip
coverage: Anonymize line numbers in branch views
The code for anonymizing line numbers in coverage reports now supports the
slightly different line number syntax used by branch regions.
-rw-r--r--src/tools/compiletest/src/runtest.rs24
-rw-r--r--src/tools/compiletest/src/runtest/tests.rs72
2 files changed, 93 insertions, 3 deletions
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index b258b748ca8..8be4def15de 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -19,7 +19,6 @@ use miropt_test_tools::{files_for_miropt_test, MiroptTest, MiroptTestFile};
 use regex::{Captures, Regex};
 use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
 
-use std::borrow::Cow;
 use std::collections::{HashMap, HashSet};
 use std::env;
 use std::ffi::{OsStr, OsString};
@@ -725,7 +724,7 @@ impl<'test> TestCx<'test> {
 
     /// 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> {
+    fn anonymize_coverage_line_numbers(coverage: &str) -> String {
         // 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`.)
@@ -733,9 +732,28 @@ impl<'test> TestCx<'test> {
         //
         // Line numbers that appear inside expansion/instantiation subviews
         // have an additional prefix of `  |` for each nesting level.
+        //
+        // Branch views also include the relevant line number, so we want to
+        // redact those too. (These line numbers don't have padding.)
+        //
+        // Note: The pattern `(?m:^)` matches the start of a line.
+
+        // `    1|` => `   LL|`
+        // `   10|` => `   LL|`
+        // `  100|` => `   LL|`
+        // `  | 1000|`    => `  |   LL|`
+        // `  |  | 1000|` => `  |  |   LL|`
         static LINE_NUMBER_RE: Lazy<Regex> =
             Lazy::new(|| Regex::new(r"(?m:^)(?<prefix>(?:  \|)*) *[0-9]+\|").unwrap());
-        LINE_NUMBER_RE.replace_all(coverage, "$prefix   LL|")
+        let coverage = LINE_NUMBER_RE.replace_all(&coverage, "${prefix}   LL|");
+
+        // `  |  Branch (1:`     => `  |  Branch (LL:`
+        // `  |  |  Branch (10:` => `  |  |  Branch (LL:`
+        static BRANCH_LINE_NUMBER_RE: Lazy<Regex> =
+            Lazy::new(|| Regex::new(r"(?m:^)(?<prefix>(?:  \|)+  Branch \()[0-9]+:").unwrap());
+        let coverage = BRANCH_LINE_NUMBER_RE.replace_all(&coverage, "${prefix}LL:");
+
+        coverage.into_owned()
     }
 
     /// Coverage reports can describe multiple source files, separated by
diff --git a/src/tools/compiletest/src/runtest/tests.rs b/src/tools/compiletest/src/runtest/tests.rs
index fb3dd326a4c..ee42243e83d 100644
--- a/src/tools/compiletest/src/runtest/tests.rs
+++ b/src/tools/compiletest/src/runtest/tests.rs
@@ -48,3 +48,75 @@ fn normalize_platform_differences() {
         r#"println!("test\ntest")"#,
     );
 }
+
+/// Test for anonymizing line numbers in coverage reports, especially for
+/// branch regions.
+///
+/// FIXME(#119681): This test can be removed when we have examples of branch
+/// coverage in the actual coverage test suite.
+#[test]
+fn anonymize_coverage_line_numbers() {
+    let anon = |coverage| TestCx::anonymize_coverage_line_numbers(coverage);
+
+    let input = r#"
+    6|      3|fn print_size<T>() {
+    7|      3|    if std::mem::size_of::<T>() > 4 {
+  ------------------
+  |  Branch (7:8): [True: 0, False: 1]
+  |  Branch (7:8): [True: 0, False: 1]
+  |  Branch (7:8): [True: 1, False: 0]
+  ------------------
+    8|      1|        println!("size > 4");
+"#;
+
+    let expected = r#"
+   LL|      3|fn print_size<T>() {
+   LL|      3|    if std::mem::size_of::<T>() > 4 {
+  ------------------
+  |  Branch (LL:8): [True: 0, False: 1]
+  |  Branch (LL:8): [True: 0, False: 1]
+  |  Branch (LL:8): [True: 1, False: 0]
+  ------------------
+   LL|      1|        println!("size > 4");
+"#;
+
+    assert_eq!(anon(input), expected);
+
+    //////////
+
+    let input = r#"
+   12|      3|}
+  ------------------
+  | branch_generics::print_size::<()>:
+  |    6|      1|fn print_size<T>() {
+  |    7|      1|    if std::mem::size_of::<T>() > 4 {
+  |  ------------------
+  |  |  Branch (7:8): [True: 0, False: 1]
+  |  ------------------
+  |    8|      0|        println!("size > 4");
+  |    9|      1|    } else {
+  |   10|      1|        println!("size <= 4");
+  |   11|      1|    }
+  |   12|      1|}
+  ------------------
+"#;
+
+    let expected = r#"
+   LL|      3|}
+  ------------------
+  | branch_generics::print_size::<()>:
+  |   LL|      1|fn print_size<T>() {
+  |   LL|      1|    if std::mem::size_of::<T>() > 4 {
+  |  ------------------
+  |  |  Branch (LL:8): [True: 0, False: 1]
+  |  ------------------
+  |   LL|      0|        println!("size > 4");
+  |   LL|      1|    } else {
+  |   LL|      1|        println!("size <= 4");
+  |   LL|      1|    }
+  |   LL|      1|}
+  ------------------
+"#;
+
+    assert_eq!(anon(input), expected);
+}