Skip to content

Commit 85b884b

Browse files
committed
Auto merge of #122997 - matthiaskrgr:compiletest_ices, r=oli-obk
compiletest ice tracking see https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/where.20to.20mass-add.20known.20ices.20.2F.20merging.20glacier.20into.20rust/near/429082963 This will allow us to sunset most of https://github.com/rust-lang/glacier The rustc ices will be tracked directly inside the rust testsuite There are a couple of .sh tests remaining that I have not ported over yet. This adds `tests/crashes`, a file inside this directory MUST ice, otherwise it is considered test-fail. This will be used to track ICEs from glacier and the bugtracker. When someones pr accidentally fixes one of these ICEs, they can move the test from `crashes` into `ui` for example. I also added a new tidy lint that warns when a test inside `tests/crashes` does not have a `//@ known-bug: ` line the env var `COMPILETEST_VERBOSE_CRASHES` can be set to get exit code, stderr and stdout of a crash-test to aid debugging/adding tests.
2 parents 9db7a74 + 2ce487c commit 85b884b

File tree

172 files changed

+3362
-7
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

172 files changed

+3362
-7
lines changed

src/bootstrap/src/core/build_steps/test.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1400,6 +1400,8 @@ impl Step for RunMakeSupport {
14001400

14011401
default_test!(Ui { path: "tests/ui", mode: "ui", suite: "ui" });
14021402

1403+
default_test!(Crashes { path: "tests/crashes", mode: "crashes", suite: "crashes" });
1404+
14031405
default_test!(RunPassValgrind {
14041406
path: "tests/run-pass-valgrind",
14051407
mode: "run-pass-valgrind",

src/bootstrap/src/core/builder.rs

+1
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,7 @@ impl<'a> Builder<'a> {
745745
test::ExpandYamlAnchors,
746746
test::Tidy,
747747
test::Ui,
748+
test::Crashes,
748749
test::RunPassValgrind,
749750
test::Coverage,
750751
test::CoverageMap,

src/tools/compiletest/src/common.rs

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ string_enum! {
6969
Assembly => "assembly",
7070
CoverageMap => "coverage-map",
7171
CoverageRun => "coverage-run",
72+
Crashes => "crashes",
7273
}
7374
}
7475

src/tools/compiletest/src/header.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,16 @@ impl TestProps {
581581
self.incremental = true;
582582
}
583583

584+
if config.mode == Mode::Crashes {
585+
// we don't want to pollute anything with backtrace-files
586+
// also turn off backtraces in order to save some execution
587+
// time on the tests; we only need to know IF it crashes
588+
self.rustc_env = vec![
589+
("RUST_BACKTRACE".to_string(), "0".to_string()),
590+
("RUSTC_ICE".to_string(), "0".to_string()),
591+
];
592+
}
593+
584594
for key in &["RUST_TEST_NOCAPTURE", "RUST_TEST_THREADS"] {
585595
if let Ok(val) = env::var(key) {
586596
if self.exec_env.iter().find(|&&(ref x, _)| x == key).is_none() {
@@ -596,7 +606,8 @@ impl TestProps {
596606

597607
fn update_fail_mode(&mut self, ln: &str, config: &Config) {
598608
let check_ui = |mode: &str| {
599-
if config.mode != Mode::Ui {
609+
// Mode::Crashes may need build-fail in order to trigger llvm errors or stack overflows
610+
if config.mode != Mode::Ui && config.mode != Mode::Crashes {
600611
panic!("`{}-fail` header is only supported in UI tests", mode);
601612
}
602613
};
@@ -625,6 +636,7 @@ impl TestProps {
625636
fn update_pass_mode(&mut self, ln: &str, revision: Option<&str>, config: &Config) {
626637
let check_no_run = |s| match (config.mode, s) {
627638
(Mode::Ui, _) => (),
639+
(Mode::Crashes, _) => (),
628640
(Mode::Codegen, "build-pass") => (),
629641
(Mode::Incremental, _) => {
630642
if revision.is_some() && !self.revisions.iter().all(|r| r.starts_with("cfail")) {
@@ -757,6 +769,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
757769
"ignore-mode-codegen-units",
758770
"ignore-mode-coverage-map",
759771
"ignore-mode-coverage-run",
772+
"ignore-mode-crashes",
760773
"ignore-mode-debuginfo",
761774
"ignore-mode-incremental",
762775
"ignore-mode-js-doc-test",

src/tools/compiletest/src/lib.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ pub fn parse_config(args: Vec<String>) -> Config {
6565
"mode",
6666
"which sort of compile tests to run",
6767
"run-pass-valgrind | pretty | debug-info | codegen | rustdoc \
68-
| rustdoc-json | codegen-units | incremental | run-make | ui | js-doc-test | mir-opt | assembly",
68+
| rustdoc-json | codegen-units | incremental | run-make | ui \
69+
| js-doc-test | mir-opt | assembly | crashes",
6970
)
7071
.reqopt(
7172
"",
@@ -82,7 +83,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
8283
.optopt("", "run", "whether to execute run-* tests", "auto | always | never")
8384
.optflag("", "ignored", "run tests marked as ignored")
8485
.optflag("", "with-debug-assertions", "whether to run tests with `ignore-debug` header")
85-
.optmulti("", "skip", "skip tests matching SUBSTRING. Can be passed multiple times", "SUBSTRING")
86+
.optmulti(
87+
"",
88+
"skip",
89+
"skip tests matching SUBSTRING. Can be passed multiple times",
90+
"SUBSTRING",
91+
)
8692
.optflag("", "exact", "filters match exactly")
8793
.optopt(
8894
"",
@@ -145,7 +151,11 @@ pub fn parse_config(args: Vec<String>) -> Config {
145151
.optflag("", "profiler-support", "is the profiler runtime enabled for this target")
146152
.optflag("h", "help", "show this message")
147153
.reqopt("", "channel", "current Rust channel", "CHANNEL")
148-
.optflag("", "git-hash", "run tests which rely on commit version being compiled into the binaries")
154+
.optflag(
155+
"",
156+
"git-hash",
157+
"run tests which rely on commit version being compiled into the binaries",
158+
)
149159
.optopt("", "edition", "default Rust edition", "EDITION")
150160
.reqopt("", "git-repository", "name of the git repository", "ORG/REPO")
151161
.reqopt("", "nightly-branch", "name of the git branch for nightly", "BRANCH");

src/tools/compiletest/src/runtest.rs

+26-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::common::{
44
expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT, UI_SVG, UI_WINDOWS_SVG,
55
};
66
use crate::common::{incremental_dir, output_base_dir, output_base_name, output_testname_unique};
7-
use crate::common::{Assembly, Incremental, JsDocTest, MirOpt, RunMake, RustdocJson, Ui};
7+
use crate::common::{Assembly, Crashes, Incremental, JsDocTest, MirOpt, RunMake, RustdocJson, Ui};
88
use crate::common::{Codegen, CodegenUnits, DebugInfo, Debugger, Rustdoc};
99
use crate::common::{CompareMode, FailMode, PassMode};
1010
use crate::common::{Config, TestPaths};
@@ -244,7 +244,7 @@ impl<'test> TestCx<'test> {
244244
/// Code executed for each revision in turn (or, if there are no
245245
/// revisions, exactly once, with revision == None).
246246
fn run_revision(&self) {
247-
if self.props.should_ice && self.config.mode != Incremental {
247+
if self.props.should_ice && self.config.mode != Incremental && self.config.mode != Crashes {
248248
self.fatal("cannot use should-ice in a test that is not cfail");
249249
}
250250
match self.config.mode {
@@ -263,6 +263,7 @@ impl<'test> TestCx<'test> {
263263
JsDocTest => self.run_js_doc_test(),
264264
CoverageMap => self.run_coverage_map_test(),
265265
CoverageRun => self.run_coverage_run_test(),
266+
Crashes => self.run_crash_test(),
266267
}
267268
}
268269

@@ -295,6 +296,7 @@ impl<'test> TestCx<'test> {
295296
match self.config.mode {
296297
JsDocTest => true,
297298
Ui => pm.is_some() || self.props.fail_mode > Some(FailMode::Build),
299+
Crashes => false,
298300
Incremental => {
299301
let revision =
300302
self.revision.expect("incremental tests require a list of revisions");
@@ -359,6 +361,27 @@ impl<'test> TestCx<'test> {
359361
self.check_forbid_output(&output_to_check, &proc_res);
360362
}
361363

364+
fn run_crash_test(&self) {
365+
let pm = self.pass_mode();
366+
let proc_res = self.compile_test(WillExecute::No, self.should_emit_metadata(pm));
367+
368+
if std::env::var("COMPILETEST_VERBOSE_CRASHES").is_ok() {
369+
eprintln!("{}", proc_res.status);
370+
eprintln!("{}", proc_res.stdout);
371+
eprintln!("{}", proc_res.stderr);
372+
eprintln!("{}", proc_res.cmdline);
373+
}
374+
375+
// if a test does not crash, consider it an error
376+
if proc_res.status.success() || matches!(proc_res.status.code(), Some(1 | 0)) {
377+
self.fatal(&format!(
378+
"test no longer crashes/triggers ICE! Please give it a mearningful name, \
379+
add a doc-comment to the start of the test explaining why it exists and \
380+
move it to tests/ui or wherever you see fit."
381+
));
382+
}
383+
}
384+
362385
fn run_rfail_test(&self) {
363386
let pm = self.pass_mode();
364387
let should_run = self.run_if_enabled();
@@ -2517,7 +2540,7 @@ impl<'test> TestCx<'test> {
25172540
rustc.arg("-Cdebug-assertions=no");
25182541
}
25192542
RunPassValgrind | Pretty | DebugInfo | Rustdoc | RustdocJson | RunMake
2520-
| CodegenUnits | JsDocTest => {
2543+
| CodegenUnits | JsDocTest | Crashes => {
25212544
// do not use JSON output
25222545
}
25232546
}

src/tools/opt-dist/src/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ llvm-config = "{llvm_config}"
9696
"tests/pretty",
9797
"tests/run-pass-valgrind",
9898
"tests/ui",
99+
"tests/crashes",
99100
];
100101
for test_path in env.skipped_tests() {
101102
args.extend(["--skip", test_path]);

src/tools/tidy/src/known_bug.rs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//! Tidy check to ensure that tests inside 'tests/crashes' have a '@known-bug' directive.
2+
3+
use crate::walk::*;
4+
use std::path::Path;
5+
6+
pub fn check(filepath: &Path, bad: &mut bool) {
7+
walk(filepath, |path, _is_dir| filter_not_rust(path), &mut |entry, contents| {
8+
let file = entry.path();
9+
if !contents.lines().any(|line| line.starts_with("//@ known-bug: ")) {
10+
tidy_error!(
11+
bad,
12+
"{} crash/ice test does not have a \"//@ known-bug: \" directive",
13+
file.display()
14+
);
15+
}
16+
});
17+
}

src/tools/tidy/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ pub mod features;
6767
pub mod fluent_alphabetical;
6868
mod fluent_used;
6969
pub(crate) mod iter_header;
70+
pub mod known_bug;
7071
pub mod mir_opt_tests;
7172
pub mod pal;
7273
pub mod run_make_tests;

src/tools/tidy/src/main.rs

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ fn main() {
3535
let library_path = root_path.join("library");
3636
let compiler_path = root_path.join("compiler");
3737
let librustdoc_path = src_path.join("librustdoc");
38+
let crashes_path = tests_path.join("crashes");
3839

3940
let args: Vec<String> = env::args().skip(1).collect();
4041
let (cfg_args, pos_args) = match args.iter().position(|arg| arg == "--") {
@@ -108,6 +109,7 @@ fn main() {
108109
check!(mir_opt_tests, &tests_path, bless);
109110
check!(rustdoc_gui_tests, &tests_path);
110111
check!(rustdoc_css_themes, &librustdoc_path);
112+
check!(known_bug, &crashes_path);
111113

112114
// Checks that only make sense for the compiler.
113115
check!(error_codes, &root_path, &[&compiler_path, &librustdoc_path], verbose);

tests/crashes/100041.rs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//@ known-bug: #100041
2+
3+
pub trait WellUnformed {
4+
type RequestNormalize;
5+
}
6+
7+
impl<T: ?Sized> WellUnformed for T {
8+
type RequestNormalize = ();
9+
}
10+
11+
pub fn latent(_: &[<[[()]] as WellUnformed>::RequestNormalize; 0]) {}
12+
13+
pub fn bang() {
14+
latent(&[]);
15+
}
16+
17+
fn main() {}

tests/crashes/101036.rs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//@ known-bug: #101036
2+
#![feature(generic_const_exprs)]
3+
4+
const fn t<const N: usize>() -> u8 {
5+
N as u8
6+
}
7+
8+
#[repr(u8)]
9+
enum T<const N: u8 = { T::<0>::A as u8 + T::<0>::B as u8 }>
10+
where
11+
[(); N as usize]:
12+
{
13+
A = t::<N>() as u8, B
14+
}

tests/crashes/101557.rs

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//@ known-bug: #101557
2+
//@ compile-flags: -Copt-level=0
3+
#![feature(generic_const_exprs)]
4+
use std::marker::PhantomData;
5+
6+
trait Trait {
7+
const CONST: usize;
8+
}
9+
10+
struct A<T: Trait> {
11+
_marker: PhantomData<T>,
12+
}
13+
14+
impl<const N: usize> Trait for [i8; N] {
15+
const CONST: usize = N;
16+
}
17+
18+
impl<const N: usize> From<usize> for A<[i8; N]> {
19+
fn from(_: usize) -> Self {
20+
todo!()
21+
}
22+
}
23+
24+
impl<T: Trait> From<A<[i8; T::CONST]>> for A<T> {
25+
fn from(_: A<[i8; T::CONST]>) -> Self {
26+
todo!()
27+
}
28+
}
29+
30+
fn f<T: Trait>() -> A<T>
31+
where
32+
[(); T::CONST]:,
33+
{
34+
// Usage of `0` is arbitrary
35+
let a = A::<[i8; T::CONST]>::from(0);
36+
A::<T>::from(a)
37+
}
38+
39+
fn main() {
40+
// Usage of `1` is arbitrary
41+
f::<[i8; 1]>();
42+
}

tests/crashes/101962.rs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//@ known-bug: #101962
2+
3+
#![feature(core_intrinsics)]
4+
5+
pub fn wrapping<T: Copy>(a: T, b: T) {
6+
let _z = core::intrinsics::wrapping_mul(a, b);
7+
}
8+
9+
fn main() {
10+
wrapping(1,2);
11+
}

tests/crashes/102047.rs

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//@ known-bug: #102047
2+
3+
struct Ty1;
4+
struct Ty2;
5+
6+
pub trait Trait<T> {}
7+
8+
pub trait WithAssoc1<'a> {
9+
type Assoc;
10+
}
11+
pub trait WithAssoc2<'a> {
12+
type Assoc;
13+
}
14+
15+
impl<T, U> Trait<for<'a> fn(<T as WithAssoc1<'a>>::Assoc, <U as WithAssoc2<'a>>::Assoc)> for (T, U)
16+
where
17+
T: for<'a> WithAssoc1<'a> + for<'a> WithAssoc2<'a, Assoc = i32>,
18+
U: for<'a> WithAssoc2<'a>,
19+
{
20+
}
21+
22+
impl WithAssoc1<'_> for Ty1 {
23+
type Assoc = ();
24+
}
25+
impl WithAssoc2<'_> for Ty1 {
26+
type Assoc = i32;
27+
}
28+
impl WithAssoc1<'_> for Ty2 {
29+
type Assoc = ();
30+
}
31+
impl WithAssoc2<'_> for Ty2 {
32+
type Assoc = u32;
33+
}
34+
35+
fn foo<T, U, V>()
36+
where
37+
T: for<'a> WithAssoc1<'a>,
38+
U: for<'a> WithAssoc2<'a>,
39+
(T, U): Trait<V>,
40+
{
41+
}
42+
43+
fn main() {
44+
foo::<Ty1, Ty2, _>();
45+
}

tests/crashes/102252.rs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//@ known-bug: #102252
2+
3+
#![feature(min_specialization, rustc_attrs)]
4+
5+
#[rustc_specialization_trait]
6+
pub trait Trait {}
7+
8+
struct Struct
9+
where
10+
Self: Iterator<Item = <Self as Iterator>::Item>, {}
11+
12+
impl Trait for Struct {}
13+
14+
fn main() {}

0 commit comments

Comments
 (0)