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, 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 { +fn contains_ui_error_patterns(file_path: &Path) -> Result { // 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 { 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( env: &Env, args: &TestArg, prepare_files_callback: F, + run_error_pattern_test: bool, test_type: &str, ) -> Result<(), String> where @@ -876,54 +889,71 @@ fn test_rustc_inner( } 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(()); + } + + walk_dir(dir, &mut dir_handling, &mut file_handling, false) + } + 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(()), - )?; - - // 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, dir_handling, file_handling) + + walk_dir(rust_path.join("tests/ui"), &mut dir_handling, &mut file_handling, false)?; } - 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); - } - Ok(()) - } - - walk_dir(rust_path.join("tests/ui"), dir_handling, file_handling)?; - let nb_parts = args.nb_parts.unwrap_or(0); if nb_parts > 0 { let current_part = args.current_part.unwrap(); @@ -1004,22 +1034,24 @@ fn file_handling(file_path: &Path) -> Result<(), String> { } 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 + '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 + '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(dir: P, mut dir_cb: D, mut file_cb: F) -> Result<(), String> +pub fn walk_dir( + dir: P, + dir_cb: &mut D, + file_cb: &mut F, + recursive: bool, +) -> Result<(), String> where P: AsRef, D: FnMut(&Path) -> Result<(), String>, @@ -358,6 +363,9 @@ pub fn walk_dir(dir: P, mut dir_cb: D, mut file_cb: F) -> Result<(), St 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