about summary refs log tree commit diff
diff options
context:
space:
mode:
authorShashank Trivedi <100513286+lordshashank@users.noreply.github.com>2024-06-11 02:43:44 +0530
committerGitHub <noreply@github.com>2024-06-10 17:13:44 -0400
commita63b83eb4e46433216dac0558b978619c6746ea8 (patch)
tree3b8fc0b971e5b6b541fba39e928dba8f7da204ff
parenteccab8ba39e9c5a3dfcf146105909039b64b0577 (diff)
downloadrust-a63b83eb4e46433216dac0558b978619c6746ea8.tar.gz
rust-a63b83eb4e46433216dac0558b978619c6746ea8.zip
ui pattern failure tests (#524)
-rw-r--r--.github/workflows/failures.yml9
-rw-r--r--build_system/src/build.rs17
-rw-r--r--build_system/src/prepare.rs15
-rw-r--r--build_system/src/test.rs150
-rw-r--r--build_system/src/utils.rs10
-rw-r--r--tests/failing-ice-tests.txt36
6 files changed, 170 insertions, 67 deletions
diff --git a/.github/workflows/failures.yml b/.github/workflows/failures.yml
index 9fa6f416c14..66129f805d4 100644
--- a/.github/workflows/failures.yml
+++ b/.github/workflows/failures.yml
@@ -98,3 +98,12 @@ jobs:
       run: |
         ${{ matrix.libgccjit_version.env_extra }} ./y.sh test --release --clean --build-sysroot --test-failing-rustc ${{ matrix.libgccjit_version.extra }} | tee output_log
         rg --text "test result" output_log >> $GITHUB_STEP_SUMMARY
+
+    - name: Run failing ui pattern tests for ICE
+      id: ui-tests
+      run: |
+        ${{ matrix.libgccjit_version.env_extra }} ./y.sh test --release --test-failing-ui-pattern-tests ${{ matrix.libgccjit_version.extra }} | tee output_log_ui
+        if grep -q "the compiler unexpectedly panicked" output_log_ui; then
+          echo "Error: 'the compiler unexpectedly panicked' found in output logs. CI Error!!"
+          exit 1
+        fi
diff --git a/build_system/src/build.rs b/build_system/src/build.rs
index ac428b4cec0..d465ab7e506 100644
--- a/build_system/src/build.rs
+++ b/build_system/src/build.rs
@@ -68,7 +68,7 @@ fn cleanup_sysroot_previous_build(start_dir: &Path) {
     // Clean target dir except for build scripts and incremental cache
     let _ = walk_dir(
         start_dir.join("target"),
-        |dir: &Path| {
+        &mut |dir: &Path| {
             for top in &["debug", "release"] {
                 let _ = fs::remove_dir_all(dir.join(top).join("build"));
                 let _ = fs::remove_dir_all(dir.join(top).join("deps"));
@@ -77,7 +77,7 @@ fn cleanup_sysroot_previous_build(start_dir: &Path) {
 
                 let _ = walk_dir(
                     dir.join(top),
-                    |sub_dir: &Path| {
+                    &mut |sub_dir: &Path| {
                         if sub_dir
                             .file_name()
                             .map(|filename| filename.to_str().unwrap().starts_with("libsysroot"))
@@ -87,7 +87,7 @@ fn cleanup_sysroot_previous_build(start_dir: &Path) {
                         }
                         Ok(())
                     },
-                    |file: &Path| {
+                    &mut |file: &Path| {
                         if file
                             .file_name()
                             .map(|filename| filename.to_str().unwrap().starts_with("libsysroot"))
@@ -97,11 +97,13 @@ fn cleanup_sysroot_previous_build(start_dir: &Path) {
                         }
                         Ok(())
                     },
+                    false,
                 );
             }
             Ok(())
         },
-        |_| Ok(()),
+        &mut |_| Ok(()),
+        false,
     );
 
     let _ = fs::remove_file(start_dir.join("Cargo.lock"));
@@ -166,14 +168,15 @@ pub fn build_sysroot(env: &HashMap<String, String>, config: &ConfigInfo) -> Resu
     // Copy files to sysroot
     let sysroot_path = start_dir.join(format!("sysroot/lib/rustlib/{}/lib/", config.target_triple));
     create_dir(&sysroot_path)?;
-    let copier = |dir_to_copy: &Path| {
+    let mut copier = |dir_to_copy: &Path| {
         // FIXME: should not use shell command!
         run_command(&[&"cp", &"-r", &dir_to_copy, &sysroot_path], None).map(|_| ())
     };
     walk_dir(
         start_dir.join(&format!("target/{}/{}/deps", config.target_triple, channel)),
-        copier,
-        copier,
+        &mut copier.clone(),
+        &mut copier,
+        false,
     )?;
 
     // Copy the source files to the sysroot (Rust for Linux needs this).
diff --git a/build_system/src/prepare.rs b/build_system/src/prepare.rs
index a085d863616..00aa632165e 100644
--- a/build_system/src/prepare.rs
+++ b/build_system/src/prepare.rs
@@ -72,30 +72,33 @@ fn prepare_libcore(
     let mut patches = Vec::new();
     walk_dir(
         "patches",
-        |_| Ok(()),
-        |file_path: &Path| {
+        &mut |_| Ok(()),
+        &mut |file_path: &Path| {
             patches.push(file_path.to_path_buf());
             Ok(())
         },
+        false,
     )?;
     if cross_compile {
         walk_dir(
             "patches/cross_patches",
-            |_| Ok(()),
-            |file_path: &Path| {
+            &mut |_| Ok(()),
+            &mut |file_path: &Path| {
                 patches.push(file_path.to_path_buf());
                 Ok(())
             },
+            false,
         )?;
     }
     if libgccjit12_patches {
         walk_dir(
             "patches/libgccjit12",
-            |_| Ok(()),
-            |file_path: &Path| {
+            &mut |_| Ok(()),
+            &mut |file_path: &Path| {
                 patches.push(file_path.to_path_buf());
                 Ok(())
             },
+            false,
         )?;
     }
     patches.sort();
diff --git a/build_system/src/test.rs b/build_system/src/test.rs
index f1b7b8d19b6..462d20d728d 100644
--- a/build_system/src/test.rs
+++ b/build_system/src/test.rs
@@ -23,6 +23,10 @@ fn get_runners() -> Runners {
     runners.insert("--test-rustc", ("Run all rustc tests", test_rustc as Runner));
     runners
         .insert("--test-successful-rustc", ("Run successful rustc tests", test_successful_rustc));
+    runners.insert(
+        "--test-failing-ui-pattern-tests",
+        ("Run failing ui pattern tests", test_failing_ui_pattern_tests),
+    );
     runners.insert("--test-failing-rustc", ("Run failing rustc tests", test_failing_rustc));
     runners.insert("--projects", ("Run the tests of popular crates", test_projects));
     runners.insert("--test-libcore", ("Run libcore tests", test_libcore));
@@ -808,7 +812,7 @@ fn extended_sysroot_tests(env: &Env, args: &TestArg) -> Result<(), String> {
     Ok(())
 }
 
-fn should_not_remove_test(file: &str) -> bool {
+fn valid_ui_error_pattern_test(file: &str) -> bool {
     // contains //~ERROR, but shouldn't be removed
     [
         "issues/auxiliary/issue-3136-a.rs",
@@ -824,7 +828,7 @@ fn should_not_remove_test(file: &str) -> bool {
 }
 
 #[rustfmt::skip]
-fn should_remove_test(file_path: &Path) -> Result<bool, String> {
+fn contains_ui_error_patterns(file_path: &Path) -> Result<bool, String> {
     // Tests generating errors.
     let file = File::open(file_path)
         .map_err(|error| format!("Failed to read `{}`: {:?}", file_path.display(), error))?;
@@ -856,10 +860,19 @@ fn should_remove_test(file_path: &Path) -> Result<bool, String> {
     Ok(false)
 }
 
+// # Parameters
+//
+// * `env`: An environment variable that provides context for the function.
+// * `args`: The arguments passed to the test. This could include things like the flags, config etc.
+// * `prepare_files_callback`: A callback function that prepares the files needed for the test. Its used to remove/retain tests giving Error to run various rust test suits.
+// * `run_error_pattern_test`: A boolean that determines whether to run only error pattern tests.
+// * `test_type`: A string that indicates the type of the test being run.
+//
 fn test_rustc_inner<F>(
     env: &Env,
     args: &TestArg,
     prepare_files_callback: F,
+    run_error_pattern_test: bool,
     test_type: &str,
 ) -> Result<(), String>
 where
@@ -876,54 +889,71 @@ where
     }
 
     if test_type == "ui" {
-        walk_dir(
-            rust_path.join("tests/ui"),
-            |dir| {
-                let dir_name = dir.file_name().and_then(|name| name.to_str()).unwrap_or("");
-                if [
-                    "abi",
-                    "extern",
-                    "unsized-locals",
-                    "proc-macro",
-                    "threads-sendsync",
-                    "borrowck",
-                    "test-attrs",
-                ]
-                .iter()
-                .any(|name| *name == dir_name)
-                {
-                    std::fs::remove_dir_all(dir).map_err(|error| {
-                        format!("Failed to remove folder `{}`: {:?}", dir.display(), error)
-                    })?;
+        if run_error_pattern_test {
+            // After we removed the error tests that are known to panic with rustc_codegen_gcc, we now remove the passing tests since this runs the error tests.
+            walk_dir(
+                rust_path.join("tests/ui"),
+                &mut |_dir| Ok(()),
+                &mut |file_path| {
+                    if contains_ui_error_patterns(file_path)? {
+                        Ok(())
+                    } else {
+                        remove_file(file_path).map_err(|e| e.to_string())
+                    }
+                },
+                true,
+            )?;
+        } else {
+            walk_dir(
+                rust_path.join("tests/ui"),
+                &mut |dir| {
+                    let dir_name = dir.file_name().and_then(|name| name.to_str()).unwrap_or("");
+                    if [
+                        "abi",
+                        "extern",
+                        "unsized-locals",
+                        "proc-macro",
+                        "threads-sendsync",
+                        "borrowck",
+                        "test-attrs",
+                    ]
+                    .iter()
+                    .any(|name| *name == dir_name)
+                    {
+                        std::fs::remove_dir_all(dir).map_err(|error| {
+                            format!("Failed to remove folder `{}`: {:?}", dir.display(), error)
+                        })?;
+                    }
+                    Ok(())
+                },
+                &mut |_| Ok(()),
+                false,
+            )?;
+
+            // These two functions are used to remove files that are known to not be working currently
+            // with the GCC backend to reduce noise.
+            fn dir_handling(dir: &Path) -> Result<(), String> {
+                if dir.file_name().map(|name| name == "auxiliary").unwrap_or(true) {
+                    return Ok(());
                 }
-                Ok(())
-            },
-            |_| Ok(()),
-        )?;
 
-        // These two functions are used to remove files that are known to not be working currently
-        // with the GCC backend to reduce noise.
-        fn dir_handling(dir: &Path) -> Result<(), String> {
-            if dir.file_name().map(|name| name == "auxiliary").unwrap_or(true) {
-                return Ok(());
+                walk_dir(dir, &mut dir_handling, &mut file_handling, false)
             }
-            walk_dir(dir, dir_handling, file_handling)
-        }
-        fn file_handling(file_path: &Path) -> Result<(), String> {
-            if !file_path.extension().map(|extension| extension == "rs").unwrap_or(false) {
-                return Ok(());
-            }
-            let path_str = file_path.display().to_string().replace("\\", "/");
-            if should_not_remove_test(&path_str) {
-                return Ok(());
-            } else if should_remove_test(file_path)? {
-                return remove_file(&file_path);
+            fn file_handling(file_path: &Path) -> Result<(), String> {
+                if !file_path.extension().map(|extension| extension == "rs").unwrap_or(false) {
+                    return Ok(());
+                }
+                let path_str = file_path.display().to_string().replace("\\", "/");
+                if valid_ui_error_pattern_test(&path_str) {
+                    return Ok(());
+                } else if contains_ui_error_patterns(file_path)? {
+                    return remove_file(&file_path);
+                }
+                Ok(())
             }
-            Ok(())
-        }
-
-        walk_dir(rust_path.join("tests/ui"), dir_handling, file_handling)?;
 
+            walk_dir(rust_path.join("tests/ui"), &mut dir_handling, &mut file_handling, false)?;
+        }
         let nb_parts = args.nb_parts.unwrap_or(0);
         if nb_parts > 0 {
             let current_part = args.current_part.unwrap();
@@ -1004,22 +1034,24 @@ where
 }
 
 fn test_rustc(env: &Env, args: &TestArg) -> Result<(), String> {
-    test_rustc_inner(env, args, |_| Ok(false), "run-make")?;
-    test_rustc_inner(env, args, |_| Ok(false), "ui")
+    test_rustc_inner(env, args, |_| Ok(false), false, "run-make")?;
+    test_rustc_inner(env, args, |_| Ok(false), false, "ui")
 }
 
 fn test_failing_rustc(env: &Env, args: &TestArg) -> Result<(), String> {
     let result1 = test_rustc_inner(
         env,
         args,
-        prepare_files_callback_failing("tests/failing-run-make-tests.txt", "run-make"),
+        retain_files_callback("tests/failing-run-make-tests.txt", "run-make"),
+        false,
         "run-make",
     );
 
     let result2 = test_rustc_inner(
         env,
         args,
-        prepare_files_callback_failing("tests/failing-ui-tests.txt", "ui"),
+        retain_files_callback("tests/failing-ui-tests.txt", "ui"),
+        false,
         "ui",
     );
 
@@ -1030,18 +1062,30 @@ fn test_successful_rustc(env: &Env, args: &TestArg) -> Result<(), String> {
     test_rustc_inner(
         env,
         args,
-        prepare_files_callback_success("tests/failing-ui-tests.txt", "ui"),
+        remove_files_callback("tests/failing-ui-tests.txt", "ui"),
+        false,
         "ui",
     )?;
     test_rustc_inner(
         env,
         args,
-        prepare_files_callback_success("tests/failing-run-make-tests.txt", "run-make"),
+        remove_files_callback("tests/failing-run-make-tests.txt", "run-make"),
+        false,
         "run-make",
     )
 }
 
-fn prepare_files_callback_failing<'a>(
+fn test_failing_ui_pattern_tests(env: &Env, args: &TestArg) -> Result<(), String> {
+    test_rustc_inner(
+        env,
+        args,
+        remove_files_callback("tests/failing-ice-tests.txt", "ui"),
+        true,
+        "ui",
+    )
+}
+
+fn retain_files_callback<'a>(
     file_path: &'a str,
     test_type: &'a str,
 ) -> impl Fn(&Path) -> Result<bool, String> + 'a {
@@ -1104,7 +1148,7 @@ fn prepare_files_callback_failing<'a>(
     }
 }
 
-fn prepare_files_callback_success<'a>(
+fn remove_files_callback<'a>(
     file_path: &'a str,
     test_type: &'a str,
 ) -> impl Fn(&Path) -> Result<bool, String> + 'a {
diff --git a/build_system/src/utils.rs b/build_system/src/utils.rs
index cdda9d4a81e..3bba8df6c65 100644
--- a/build_system/src/utils.rs
+++ b/build_system/src/utils.rs
@@ -343,7 +343,12 @@ pub fn git_clone_root_dir(
     git_clone_inner(to_clone, &dest_parent_dir.join(&repo_name), shallow_clone, repo_name)
 }
 
-pub fn walk_dir<P, D, F>(dir: P, mut dir_cb: D, mut file_cb: F) -> Result<(), String>
+pub fn walk_dir<P, D, F>(
+    dir: P,
+    dir_cb: &mut D,
+    file_cb: &mut F,
+    recursive: bool,
+) -> Result<(), String>
 where
     P: AsRef<Path>,
     D: FnMut(&Path) -> Result<(), String>,
@@ -358,6 +363,9 @@ where
         let entry_path = entry.path();
         if entry_path.is_dir() {
             dir_cb(&entry_path)?;
+            if recursive {
+                walk_dir(entry_path, dir_cb, file_cb, recursive)?; // Recursive call
+            }
         } else {
             file_cb(&entry_path)?;
         }
diff --git a/tests/failing-ice-tests.txt b/tests/failing-ice-tests.txt
new file mode 100644
index 00000000000..2084f86b62e
--- /dev/null
+++ b/tests/failing-ice-tests.txt
@@ -0,0 +1,36 @@
+tests/ui/treat-err-as-bug/span_delayed_bug.rs
+tests/ui/treat-err-as-bug/err.rs
+tests/ui/simd/not-out-of-bounds.rs
+tests/ui/simd/monomorphize-shuffle-index.rs
+tests/ui/simd/masked-load-store-build-fail.rs
+tests/ui/simd/intrinsic/generic-shuffle.rs
+tests/ui/simd/intrinsic/generic-elements.rs
+tests/ui/simd/intrinsic/generic-cast.rs
+tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs
+tests/ui/simd/intrinsic/generic-arithmetic-2.rs
+tests/ui/panics/default-backtrace-ice.rs
+tests/ui/mir/lint/storage-live.rs
+tests/ui/layout/valid_range_oob.rs
+tests/ui/higher-ranked/trait-bounds/future.rs
+tests/ui/consts/const-eval/const-eval-query-stack.rs
+tests/ui/simd/masked-load-store.rs
+tests/ui/simd/issue-39720.rs
+tests/ui/simd/intrinsic/ptr-cast.rs
+tests/ui/sepcomp/sepcomp-statics.rs
+tests/ui/sepcomp/sepcomp-fns.rs
+tests/ui/sepcomp/sepcomp-fns-backwards.rs
+tests/ui/sepcomp/sepcomp-extern.rs
+tests/ui/sepcomp/sepcomp-cci.rs
+tests/ui/lto/thin-lto-inlines2.rs
+tests/ui/lto/weak-works.rs
+tests/ui/lto/thin-lto-inlines.rs
+tests/ui/lto/thin-lto-global-allocator.rs
+tests/ui/lto/msvc-imp-present.rs
+tests/ui/lto/dylib-works.rs
+tests/ui/lto/all-crates.rs
+tests/ui/issues/issue-47364.rs
+tests/ui/functions-closures/parallel-codegen-closures.rs
+tests/ui/sepcomp/sepcomp-unwind.rs
+tests/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs
+tests/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs
+tests/ui/unwind-no-uwtable.rs