diff options
Diffstat (limited to 'src/tools/compiletest/src/directives.rs')
| -rw-r--r-- | src/tools/compiletest/src/directives.rs | 339 |
1 files changed, 291 insertions, 48 deletions
diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs index a6242cf0c22..93133ea0bfd 100644 --- a/src/tools/compiletest/src/directives.rs +++ b/src/tools/compiletest/src/directives.rs @@ -9,7 +9,7 @@ use camino::{Utf8Path, Utf8PathBuf}; use semver::Version; use tracing::*; -use crate::common::{Config, Debugger, FailMode, Mode, PassMode}; +use crate::common::{Config, Debugger, FailMode, PassMode, TestMode}; use crate::debuggers::{extract_cdb_version, extract_gdb_version}; use crate::directives::auxiliary::{AuxProps, parse_and_update_aux}; use crate::directives::needs::CachedNeedsConditions; @@ -56,7 +56,6 @@ impl EarlyProps { let mut poisoned = false; iter_directives( config.mode, - &config.suite, &mut poisoned, testfile, rdr, @@ -328,7 +327,7 @@ impl TestProps { props.exec_env.push(("RUSTC".to_string(), config.rustc_path.to_string())); match (props.pass_mode, props.fail_mode) { - (None, None) if config.mode == Mode::Ui => props.fail_mode = Some(FailMode::Check), + (None, None) if config.mode == TestMode::Ui => props.fail_mode = Some(FailMode::Check), (Some(_), Some(_)) => panic!("cannot use a *-fail and *-pass mode together"), _ => {} } @@ -349,7 +348,6 @@ impl TestProps { iter_directives( config.mode, - &config.suite, &mut poisoned, testfile, file, @@ -609,11 +607,11 @@ impl TestProps { self.failure_status = Some(101); } - if config.mode == Mode::Incremental { + if config.mode == TestMode::Incremental { self.incremental = true; } - if config.mode == Mode::Crashes { + if config.mode == TestMode::Crashes { // we don't want to pollute anything with backtrace-files // also turn off backtraces in order to save some execution // time on the tests; we only need to know IF it crashes @@ -641,11 +639,11 @@ impl TestProps { fn update_fail_mode(&mut self, ln: &str, config: &Config) { let check_ui = |mode: &str| { // Mode::Crashes may need build-fail in order to trigger llvm errors or stack overflows - if config.mode != Mode::Ui && config.mode != Mode::Crashes { + if config.mode != TestMode::Ui && config.mode != TestMode::Crashes { panic!("`{}-fail` directive is only supported in UI tests", mode); } }; - if config.mode == Mode::Ui && config.parse_name_directive(ln, "compile-fail") { + if config.mode == TestMode::Ui && config.parse_name_directive(ln, "compile-fail") { panic!("`compile-fail` directive is useless in UI tests"); } let fail_mode = if config.parse_name_directive(ln, "check-fail") { @@ -669,10 +667,10 @@ impl TestProps { fn update_pass_mode(&mut self, ln: &str, revision: Option<&str>, config: &Config) { let check_no_run = |s| match (config.mode, s) { - (Mode::Ui, _) => (), - (Mode::Crashes, _) => (), - (Mode::Codegen, "build-pass") => (), - (Mode::Incremental, _) => { + (TestMode::Ui, _) => (), + (TestMode::Crashes, _) => (), + (TestMode::Codegen, "build-pass") => (), + (TestMode::Incremental, _) => { if revision.is_some() && !self.revisions.iter().all(|r| r.starts_with("cfail")) { panic!("`{s}` directive is only supported in `cfail` incremental tests") } @@ -715,7 +713,7 @@ impl TestProps { pub fn update_add_core_stubs(&mut self, ln: &str, config: &Config) { let add_core_stubs = config.parse_name_directive(ln, directives::ADD_CORE_STUBS); if add_core_stubs { - if !matches!(config.mode, Mode::Ui | Mode::Codegen | Mode::Assembly) { + if !matches!(config.mode, TestMode::Ui | TestMode::Codegen | TestMode::Assembly) { panic!( "`add-core-stubs` is currently only supported for ui, codegen and assembly test modes" ); @@ -765,11 +763,267 @@ fn line_directive<'line>( Some(DirectiveLine { line_number, revision, raw_directive }) } -// To prevent duplicating the list of directives between `compiletest`,`htmldocck` and `jsondocck`, -// we put it into a common file which is included in rust code and parsed here. -// FIXME: This setup is temporary until we figure out how to improve this situation. -// See <https://github.com/rust-lang/rust/issues/125813#issuecomment-2141953780>. -include!("directive-list.rs"); +/// This was originally generated by collecting directives from ui tests and then extracting their +/// directive names. This is **not** an exhaustive list of all possible directives. Instead, this is +/// a best-effort approximation for diagnostics. Add new directives to this list when needed. +const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ + // tidy-alphabetical-start + "add-core-stubs", + "assembly-output", + "aux-bin", + "aux-build", + "aux-codegen-backend", + "aux-crate", + "build-aux-docs", + "build-fail", + "build-pass", + "check-fail", + "check-pass", + "check-run-results", + "check-stdout", + "check-test-line-numbers-match", + "compile-flags", + "doc-flags", + "dont-check-compiler-stderr", + "dont-check-compiler-stdout", + "dont-check-failure-status", + "dont-require-annotations", + "edition", + "error-pattern", + "exact-llvm-major-version", + "exec-env", + "failure-status", + "filecheck-flags", + "forbid-output", + "force-host", + "ignore-16bit", + "ignore-32bit", + "ignore-64bit", + "ignore-aarch64", + "ignore-aarch64-pc-windows-msvc", + "ignore-aarch64-unknown-linux-gnu", + "ignore-aix", + "ignore-android", + "ignore-apple", + "ignore-arm", + "ignore-arm-unknown-linux-gnueabi", + "ignore-arm-unknown-linux-gnueabihf", + "ignore-arm-unknown-linux-musleabi", + "ignore-arm-unknown-linux-musleabihf", + "ignore-auxiliary", + "ignore-avr", + "ignore-beta", + "ignore-cdb", + "ignore-compare-mode-next-solver", + "ignore-compare-mode-polonius", + "ignore-coverage-map", + "ignore-coverage-run", + "ignore-cross-compile", + "ignore-eabi", + "ignore-elf", + "ignore-emscripten", + "ignore-endian-big", + "ignore-enzyme", + "ignore-freebsd", + "ignore-fuchsia", + "ignore-gdb", + "ignore-gdb-version", + "ignore-gnu", + "ignore-haiku", + "ignore-horizon", + "ignore-i686-pc-windows-gnu", + "ignore-i686-pc-windows-msvc", + "ignore-illumos", + "ignore-ios", + "ignore-linux", + "ignore-lldb", + "ignore-llvm-version", + "ignore-loongarch32", + "ignore-loongarch64", + "ignore-macabi", + "ignore-macos", + "ignore-msp430", + "ignore-msvc", + "ignore-musl", + "ignore-netbsd", + "ignore-nightly", + "ignore-none", + "ignore-nto", + "ignore-nvptx64", + "ignore-nvptx64-nvidia-cuda", + "ignore-openbsd", + "ignore-pass", + "ignore-powerpc", + "ignore-remote", + "ignore-riscv64", + "ignore-rustc-debug-assertions", + "ignore-rustc_abi-x86-sse2", + "ignore-s390x", + "ignore-sgx", + "ignore-sparc64", + "ignore-spirv", + "ignore-stable", + "ignore-stage1", + "ignore-stage2", + "ignore-std-debug-assertions", + "ignore-test", + "ignore-thumb", + "ignore-thumbv8m.base-none-eabi", + "ignore-thumbv8m.main-none-eabi", + "ignore-tvos", + "ignore-unix", + "ignore-unknown", + "ignore-uwp", + "ignore-visionos", + "ignore-vxworks", + "ignore-wasi", + "ignore-wasm", + "ignore-wasm32", + "ignore-wasm32-bare", + "ignore-wasm64", + "ignore-watchos", + "ignore-windows", + "ignore-windows-gnu", + "ignore-windows-msvc", + "ignore-x32", + "ignore-x86", + "ignore-x86_64", + "ignore-x86_64-apple-darwin", + "ignore-x86_64-pc-windows-gnu", + "ignore-x86_64-unknown-linux-gnu", + "incremental", + "known-bug", + "llvm-cov-flags", + "max-llvm-major-version", + "min-cdb-version", + "min-gdb-version", + "min-lldb-version", + "min-llvm-version", + "min-system-llvm-version", + "needs-asm-support", + "needs-crate-type", + "needs-deterministic-layouts", + "needs-dlltool", + "needs-dynamic-linking", + "needs-enzyme", + "needs-force-clang-based-tests", + "needs-git-hash", + "needs-llvm-components", + "needs-llvm-zstd", + "needs-profiler-runtime", + "needs-relocation-model-pic", + "needs-run-enabled", + "needs-rust-lld", + "needs-rustc-debug-assertions", + "needs-sanitizer-address", + "needs-sanitizer-cfi", + "needs-sanitizer-dataflow", + "needs-sanitizer-hwaddress", + "needs-sanitizer-kcfi", + "needs-sanitizer-leak", + "needs-sanitizer-memory", + "needs-sanitizer-memtag", + "needs-sanitizer-safestack", + "needs-sanitizer-shadow-call-stack", + "needs-sanitizer-support", + "needs-sanitizer-thread", + "needs-std-debug-assertions", + "needs-subprocess", + "needs-symlink", + "needs-target-has-atomic", + "needs-target-std", + "needs-threads", + "needs-unwind", + "needs-wasmtime", + "needs-xray", + "no-auto-check-cfg", + "no-prefer-dynamic", + "normalize-stderr", + "normalize-stderr-32bit", + "normalize-stderr-64bit", + "normalize-stdout", + "only-16bit", + "only-32bit", + "only-64bit", + "only-aarch64", + "only-aarch64-apple-darwin", + "only-aarch64-unknown-linux-gnu", + "only-apple", + "only-arm", + "only-avr", + "only-beta", + "only-bpf", + "only-cdb", + "only-dist", + "only-elf", + "only-emscripten", + "only-gnu", + "only-i686-pc-windows-gnu", + "only-i686-pc-windows-msvc", + "only-i686-unknown-linux-gnu", + "only-ios", + "only-linux", + "only-loongarch32", + "only-loongarch64", + "only-loongarch64-unknown-linux-gnu", + "only-macos", + "only-mips", + "only-mips64", + "only-msp430", + "only-msvc", + "only-musl", + "only-nightly", + "only-nvptx64", + "only-powerpc", + "only-riscv64", + "only-rustc_abi-x86-sse2", + "only-s390x", + "only-sparc", + "only-sparc64", + "only-stable", + "only-thumb", + "only-tvos", + "only-unix", + "only-visionos", + "only-wasm32", + "only-wasm32-bare", + "only-wasm32-wasip1", + "only-watchos", + "only-windows", + "only-windows-gnu", + "only-windows-msvc", + "only-x86", + "only-x86_64", + "only-x86_64-apple-darwin", + "only-x86_64-fortanix-unknown-sgx", + "only-x86_64-pc-windows-gnu", + "only-x86_64-pc-windows-msvc", + "only-x86_64-unknown-linux-gnu", + "pp-exact", + "pretty-compare-only", + "pretty-mode", + "proc-macro", + "reference", + "regex-error-pattern", + "remap-src-base", + "revisions", + "run-fail", + "run-flags", + "run-pass", + "run-rustfix", + "rustc-env", + "rustfix-only-machine-applicable", + "should-fail", + "should-ice", + "stderr-per-bitwidth", + "test-mir-pass", + "unique-doc-out-dir", + "unset-exec-env", + "unset-rustc-env", + // Used by the tidy check `unknown_revision`. + "unused-revision-names", + // tidy-alphabetical-end +]; const KNOWN_HTMLDOCCK_DIRECTIVE_NAMES: &[&str] = &[ "count", @@ -833,43 +1087,33 @@ pub(crate) struct CheckDirectiveResult<'ln> { pub(crate) fn check_directive<'a>( directive_ln: &'a str, - mode: Mode, - original_line: &str, + mode: TestMode, ) -> CheckDirectiveResult<'a> { let (directive_name, post) = directive_ln.split_once([':', ' ']).unwrap_or((directive_ln, "")); + let is_known_directive = KNOWN_DIRECTIVE_NAMES.contains(&directive_name) + || match mode { + TestMode::Rustdoc => KNOWN_HTMLDOCCK_DIRECTIVE_NAMES.contains(&directive_name), + TestMode::RustdocJson => KNOWN_JSONDOCCK_DIRECTIVE_NAMES.contains(&directive_name), + _ => false, + }; + let trailing = post.trim().split_once(' ').map(|(pre, _)| pre).unwrap_or(post); - let is_known = |s: &str| { - KNOWN_DIRECTIVE_NAMES.contains(&s) - || match mode { - Mode::Rustdoc | Mode::RustdocJson => { - original_line.starts_with("//@") - && match mode { - Mode::Rustdoc => KNOWN_HTMLDOCCK_DIRECTIVE_NAMES, - Mode::RustdocJson => KNOWN_JSONDOCCK_DIRECTIVE_NAMES, - _ => unreachable!(), - } - .contains(&s) - } - _ => false, - } - }; let trailing_directive = { // 1. is the directive name followed by a space? (to exclude `:`) - matches!(directive_ln.get(directive_name.len()..), Some(s) if s.starts_with(' ')) + directive_ln.get(directive_name.len()..).is_some_and(|s| s.starts_with(' ')) // 2. is what is after that directive also a directive (ex: "only-x86 only-arm") - && is_known(trailing) + && KNOWN_DIRECTIVE_NAMES.contains(&trailing) } .then_some(trailing); - CheckDirectiveResult { is_known_directive: is_known(&directive_name), trailing_directive } + CheckDirectiveResult { is_known_directive, trailing_directive } } const COMPILETEST_DIRECTIVE_PREFIX: &str = "//@"; fn iter_directives( - mode: Mode, - _suite: &str, + mode: TestMode, poisoned: &mut bool, testfile: &Utf8Path, rdr: impl Read, @@ -883,7 +1127,7 @@ fn iter_directives( // specify them manually in every test file. // // FIXME(jieyouxu): I feel like there's a better way to do this, leaving for later. - if mode == Mode::CoverageRun { + if mode == TestMode::CoverageRun { let extra_directives: &[&str] = &[ "needs-profiler-runtime", // FIXME(pietroalbini): this test currently does not work on cross-compiled targets @@ -914,9 +1158,9 @@ fn iter_directives( }; // Perform unknown directive check on Rust files. - if testfile.extension().map(|e| e == "rs").unwrap_or(false) { + if testfile.extension() == Some("rs") { let CheckDirectiveResult { is_known_directive, trailing_directive } = - check_directive(directive_line.raw_directive, mode, ln); + check_directive(directive_line.raw_directive, mode); if !is_known_directive { *poisoned = true; @@ -936,7 +1180,7 @@ fn iter_directives( "{testfile}:{line_number}: detected trailing compiletest test directive `{}`", trailing_directive, ); - help!("put the trailing directive in it's own line: `//@ {}`", trailing_directive); + help!("put the trailing directive in its own line: `//@ {}`", trailing_directive); return; } @@ -964,7 +1208,7 @@ impl Config { ["CHECK", "COM", "NEXT", "SAME", "EMPTY", "NOT", "COUNT", "DAG", "LABEL"]; if let Some(raw) = self.parse_name_value_directive(line, "revisions") { - if self.mode == Mode::RunMake { + if self.mode == TestMode::RunMake { panic!("`run-make` tests do not support revisions: {}", testfile); } @@ -981,7 +1225,7 @@ impl Config { ); } - if matches!(self.mode, Mode::Assembly | Mode::Codegen | Mode::MirOpt) + if matches!(self.mode, TestMode::Assembly | TestMode::Codegen | TestMode::MirOpt) && FILECHECK_FORBIDDEN_REVISION_NAMES.contains(&revision) { panic!( @@ -1388,7 +1632,6 @@ pub(crate) fn make_test_description<R: Read>( // Scan through the test file to handle `ignore-*`, `only-*`, and `needs-*` directives. iter_directives( config.mode, - &config.suite, &mut local_poisoned, path, src, @@ -1443,7 +1686,7 @@ pub(crate) fn make_test_description<R: Read>( // since we run the pretty printer across all tests by default. // If desired, we could add a `should-fail-pretty` annotation. let should_panic = match config.mode { - crate::common::Pretty => ShouldPanic::No, + TestMode::Pretty => ShouldPanic::No, _ if should_fail => ShouldPanic::Yes, _ => ShouldPanic::No, }; |
