diff options
Diffstat (limited to 'src/tools/compiletest')
| -rw-r--r-- | src/tools/compiletest/src/common.rs | 211 | ||||
| -rw-r--r-- | src/tools/compiletest/src/debuggers.rs | 11 | ||||
| -rw-r--r-- | src/tools/compiletest/src/directive-list.rs | 260 | ||||
| -rw-r--r-- | src/tools/compiletest/src/directives.rs | 339 | ||||
| -rw-r--r-- | src/tools/compiletest/src/directives/tests.rs | 4 | ||||
| -rw-r--r-- | src/tools/compiletest/src/lib.rs | 22 | ||||
| -rw-r--r-- | src/tools/compiletest/src/runtest.rs | 124 | ||||
| -rw-r--r-- | src/tools/compiletest/src/runtest/coverage.rs | 4 | ||||
| -rw-r--r-- | src/tools/compiletest/src/runtest/run_make.rs | 13 | ||||
| -rw-r--r-- | src/tools/compiletest/src/runtest/rustdoc.rs | 2 | ||||
| -rw-r--r-- | src/tools/compiletest/src/runtest/rustdoc_json.rs | 2 | ||||
| -rw-r--r-- | src/tools/compiletest/src/tests.rs | 6 | ||||
| -rw-r--r-- | src/tools/compiletest/src/util.rs | 39 |
13 files changed, 578 insertions, 459 deletions
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 7122746fa87..33da1a25db1 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -1,63 +1,20 @@ use std::collections::{BTreeSet, HashMap, HashSet}; +use std::iter; use std::process::Command; -use std::str::FromStr; use std::sync::OnceLock; -use std::{fmt, iter}; use build_helper::git::GitConfig; use camino::{Utf8Path, Utf8PathBuf}; use semver::Version; use serde::de::{Deserialize, Deserializer, Error as _}; -pub use self::Mode::*; use crate::executor::{ColorConfig, OutputFormat}; use crate::fatal; -use crate::util::{Utf8PathBufExt, add_dylib_path}; - -macro_rules! string_enum { - ($(#[$meta:meta])* $vis:vis enum $name:ident { $($variant:ident => $repr:expr,)* }) => { - $(#[$meta])* - $vis enum $name { - $($variant,)* - } - - impl $name { - $vis const VARIANTS: &'static [Self] = &[$(Self::$variant,)*]; - $vis const STR_VARIANTS: &'static [&'static str] = &[$(Self::$variant.to_str(),)*]; - - $vis const fn to_str(&self) -> &'static str { - match self { - $(Self::$variant => $repr,)* - } - } - } - - impl fmt::Display for $name { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self.to_str(), f) - } - } - - impl FromStr for $name { - type Err = String; - - fn from_str(s: &str) -> Result<Self, Self::Err> { - match s { - $($repr => Ok(Self::$variant),)* - _ => Err(format!(concat!("unknown `", stringify!($name), "` variant: `{}`"), s)), - } - } - } - } -} - -// Make the macro visible outside of this module, for tests. -#[cfg(test)] -pub(crate) use string_enum; +use crate::util::{Utf8PathBufExt, add_dylib_path, string_enum}; string_enum! { #[derive(Clone, Copy, PartialEq, Debug)] - pub enum Mode { + pub enum TestMode { Pretty => "pretty", DebugInfo => "debuginfo", Codegen => "codegen", @@ -76,18 +33,12 @@ string_enum! { } } -impl Default for Mode { - fn default() -> Self { - Mode::Ui - } -} - -impl Mode { +impl TestMode { pub fn aux_dir_disambiguator(self) -> &'static str { // Pretty-printing tests could run concurrently, and if they do, // they need to keep their output segregated. match self { - Pretty => ".pretty", + TestMode::Pretty => ".pretty", _ => "", } } @@ -96,12 +47,38 @@ impl Mode { // Coverage tests use the same test files for multiple test modes, // so each mode should have a separate output directory. match self { - CoverageMap | CoverageRun => self.to_str(), + TestMode::CoverageMap | TestMode::CoverageRun => self.to_str(), _ => "", } } } +// Note that coverage tests use the same test files for multiple test modes. +string_enum! { + #[derive(Clone, Copy, PartialEq, Debug)] + pub enum TestSuite { + Assembly => "assembly", + Codegen => "codegen", + CodegenUnits => "codegen-units", + Coverage => "coverage", + CoverageRunRustdoc => "coverage-run-rustdoc", + Crashes => "crashes", + Debuginfo => "debuginfo", + Incremental => "incremental", + MirOpt => "mir-opt", + Pretty => "pretty", + RunMake => "run-make", + Rustdoc => "rustdoc", + RustdocGui => "rustdoc-gui", + RustdocJs => "rustdoc-js", + RustdocJsStd=> "rustdoc-js-std", + RustdocJson => "rustdoc-json", + RustdocUi => "rustdoc-ui", + Ui => "ui", + UiFullDeps => "ui-fulldeps", + } +} + string_enum! { #[derive(Clone, Copy, PartialEq, Debug, Hash)] pub enum PassMode { @@ -193,9 +170,9 @@ pub enum Sanitizer { /// /// FIXME: audit these options to make sure we are not hashing less than necessary for build stamp /// (for changed test detection). -#[derive(Debug, Default, Clone)] +#[derive(Debug, Clone)] pub struct Config { - /// Some test [`Mode`]s support [snapshot testing], where a *reference snapshot* of outputs (of + /// Some [`TestMode`]s support [snapshot testing], where a *reference snapshot* of outputs (of /// `stdout`, `stderr`, or other form of artifacts) can be compared to the *actual output*. /// /// This option can be set to `true` to update the *reference snapshots* in-place, otherwise @@ -317,23 +294,21 @@ pub struct Config { /// FIXME: reconsider this string; this is hashed for test build stamp. pub stage_id: String, - /// The test [`Mode`]. E.g. [`Mode::Ui`]. Each test mode can correspond to one or more test + /// The [`TestMode`]. E.g. [`TestMode::Ui`]. Each test mode can correspond to one or more test /// suites. /// /// FIXME: stop using stringly-typed test suites! - pub mode: Mode, + pub mode: TestMode, /// The test suite. /// - /// Example: `tests/ui/` is the "UI" test *suite*, which happens to also be of the [`Mode::Ui`] - /// test *mode*. - /// - /// Note that the same test directory (e.g. `tests/coverage/`) may correspond to multiple test - /// modes, e.g. `tests/coverage/` can be run under both [`Mode::CoverageRun`] and - /// [`Mode::CoverageMap`]. + /// Example: `tests/ui/` is [`TestSuite::Ui`] test *suite*, which happens to also be of the + /// [`TestMode::Ui`] test *mode*. /// - /// FIXME: stop using stringly-typed test suites! - pub suite: String, + /// Note that the same test suite (e.g. `tests/coverage/`) may correspond to multiple test + /// modes, e.g. `tests/coverage/` can be run under both [`TestMode::CoverageRun`] and + /// [`TestMode::CoverageMap`]. + pub suite: TestSuite, /// When specified, **only** the specified [`Debugger`] will be used to run against the /// `tests/debuginfo` test suite. When unspecified, `compiletest` will attempt to find all three @@ -653,6 +628,108 @@ pub struct Config { } impl Config { + /// Incomplete config intended for `src/tools/rustdoc-gui-test` **only** as + /// `src/tools/rustdoc-gui-test` wants to reuse `compiletest`'s directive -> test property + /// handling for `//@ {compile,run}-flags`, do not use for any other purpose. + /// + /// FIXME(#143827): this setup feels very hacky. It so happens that `tests/rustdoc-gui/` + /// **only** uses `//@ {compile,run}-flags` for now and not any directives that actually rely on + /// info that is assumed available in a fully populated [`Config`]. + pub fn incomplete_for_rustdoc_gui_test() -> Config { + // FIXME(#143827): spelling this out intentionally, because this is questionable. + // + // For instance, `//@ ignore-stage1` will not work at all. + Config { + mode: TestMode::Rustdoc, + // E.g. this has no sensible default tbh. + suite: TestSuite::Ui, + + // Dummy values. + edition: Default::default(), + bless: Default::default(), + fail_fast: Default::default(), + compile_lib_path: Utf8PathBuf::default(), + run_lib_path: Utf8PathBuf::default(), + rustc_path: Utf8PathBuf::default(), + cargo_path: Default::default(), + stage0_rustc_path: Default::default(), + rustdoc_path: Default::default(), + coverage_dump_path: Default::default(), + python: Default::default(), + jsondocck_path: Default::default(), + jsondoclint_path: Default::default(), + llvm_filecheck: Default::default(), + llvm_bin_dir: Default::default(), + run_clang_based_tests_with: Default::default(), + src_root: Utf8PathBuf::default(), + src_test_suite_root: Utf8PathBuf::default(), + build_root: Utf8PathBuf::default(), + build_test_suite_root: Utf8PathBuf::default(), + sysroot_base: Utf8PathBuf::default(), + stage: Default::default(), + stage_id: String::default(), + debugger: Default::default(), + run_ignored: Default::default(), + with_rustc_debug_assertions: Default::default(), + with_std_debug_assertions: Default::default(), + filters: Default::default(), + skip: Default::default(), + filter_exact: Default::default(), + force_pass_mode: Default::default(), + run: Default::default(), + runner: Default::default(), + host_rustcflags: Default::default(), + target_rustcflags: Default::default(), + rust_randomized_layout: Default::default(), + optimize_tests: Default::default(), + target: Default::default(), + host: Default::default(), + cdb: Default::default(), + cdb_version: Default::default(), + gdb: Default::default(), + gdb_version: Default::default(), + lldb_version: Default::default(), + llvm_version: Default::default(), + system_llvm: Default::default(), + android_cross_path: Default::default(), + adb_path: Default::default(), + adb_test_dir: Default::default(), + adb_device_status: Default::default(), + lldb_python_dir: Default::default(), + verbose: Default::default(), + format: Default::default(), + color: Default::default(), + remote_test_client: Default::default(), + compare_mode: Default::default(), + rustfix_coverage: Default::default(), + has_html_tidy: Default::default(), + has_enzyme: Default::default(), + channel: Default::default(), + git_hash: Default::default(), + cc: Default::default(), + cxx: Default::default(), + cflags: Default::default(), + cxxflags: Default::default(), + ar: Default::default(), + target_linker: Default::default(), + host_linker: Default::default(), + llvm_components: Default::default(), + nodejs: Default::default(), + npm: Default::default(), + force_rerun: Default::default(), + only_modified: Default::default(), + target_cfgs: Default::default(), + builtin_cfg_names: Default::default(), + supported_crate_types: Default::default(), + nocapture: Default::default(), + nightly_branch: Default::default(), + git_merge_commit_email: Default::default(), + profiler_runtime: Default::default(), + diff_command: Default::default(), + minicore_path: Default::default(), + } + } + /// FIXME: this run scheme is... confusing. pub fn run_enabled(&self) -> bool { self.run.unwrap_or_else(|| { diff --git a/src/tools/compiletest/src/debuggers.rs b/src/tools/compiletest/src/debuggers.rs index 0edc3d82d4f..8afe3289fa4 100644 --- a/src/tools/compiletest/src/debuggers.rs +++ b/src/tools/compiletest/src/debuggers.rs @@ -51,17 +51,6 @@ pub(crate) fn configure_gdb(config: &Config) -> Option<Arc<Config>> { pub(crate) fn configure_lldb(config: &Config) -> Option<Arc<Config>> { config.lldb_python_dir.as_ref()?; - // FIXME: this is super old - if let Some(350) = config.lldb_version { - println!( - "WARNING: The used version of LLDB (350) has a \ - known issue that breaks debuginfo tests. See \ - issue #32520 for more information. Skipping all \ - LLDB-based tests!", - ); - return None; - } - Some(Arc::new(Config { debugger: Some(Debugger::Lldb), ..config.clone() })) } diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs deleted file mode 100644 index adf2a7bffef..00000000000 --- a/src/tools/compiletest/src/directive-list.rs +++ /dev/null @@ -1,260 +0,0 @@ -/// 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-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 -]; 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, }; diff --git a/src/tools/compiletest/src/directives/tests.rs b/src/tools/compiletest/src/directives/tests.rs index d4570f82677..5682cc57b6f 100644 --- a/src/tools/compiletest/src/directives/tests.rs +++ b/src/tools/compiletest/src/directives/tests.rs @@ -7,7 +7,7 @@ use super::{ DirectivesCache, EarlyProps, extract_llvm_version, extract_version_range, iter_directives, parse_normalize_rule, }; -use crate::common::{Config, Debugger, Mode}; +use crate::common::{Config, Debugger, TestMode}; use crate::executor::{CollectedTestDesc, ShouldPanic}; fn make_test_description<R: Read>( @@ -785,7 +785,7 @@ fn threads_support() { fn run_path(poisoned: &mut bool, path: &Utf8Path, buf: &[u8]) { let rdr = std::io::Cursor::new(&buf); - iter_directives(Mode::Ui, "ui", poisoned, path, rdr, &mut |_| {}); + iter_directives(TestMode::Ui, poisoned, path, rdr, &mut |_| {}); } #[test] diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 9819079e284..f3b3605a120 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -39,8 +39,8 @@ use walkdir::WalkDir; use self::directives::{EarlyProps, make_test_description}; use crate::common::{ - CompareMode, Config, Debugger, Mode, PassMode, TestPaths, UI_EXTENSIONS, expected_output_path, - output_base_dir, output_relative_path, + CompareMode, Config, Debugger, PassMode, TestMode, TestPaths, UI_EXTENSIONS, + expected_output_path, output_base_dir, output_relative_path, }; use crate::directives::DirectivesCache; use crate::executor::{CollectedTest, ColorConfig, OutputFormat}; @@ -268,7 +268,7 @@ pub fn parse_config(args: Vec<String>) -> Config { let with_rustc_debug_assertions = matches.opt_present("with-rustc-debug-assertions"); let with_std_debug_assertions = matches.opt_present("with-std-debug-assertions"); let mode = matches.opt_str("mode").unwrap().parse().expect("invalid mode"); - let has_html_tidy = if mode == Mode::Rustdoc { + let has_html_tidy = if mode == TestMode::Rustdoc { Command::new("tidy") .arg("--version") .stdout(Stdio::null()) @@ -279,7 +279,7 @@ pub fn parse_config(args: Vec<String>) -> Config { false }; let has_enzyme = matches.opt_present("has-enzyme"); - let filters = if mode == Mode::RunMake { + let filters = if mode == TestMode::RunMake { matches .free .iter() @@ -360,7 +360,7 @@ pub fn parse_config(args: Vec<String>) -> Config { stage_id: matches.opt_str("stage-id").unwrap(), mode, - suite: matches.opt_str("suite").unwrap(), + suite: matches.opt_str("suite").unwrap().parse().expect("invalid suite"), debugger: matches.opt_str("debugger").map(|debugger| { debugger .parse::<Debugger>() @@ -545,7 +545,7 @@ pub fn run_tests(config: Arc<Config>) { unsafe { env::set_var("TARGET", &config.target) }; let mut configs = Vec::new(); - if let Mode::DebugInfo = config.mode { + if let TestMode::DebugInfo = config.mode { // Debugging emscripten code doesn't make sense today if !config.target.contains("emscripten") { match config.debugger { @@ -783,7 +783,7 @@ fn collect_tests_from_dir( } // For run-make tests, a "test file" is actually a directory that contains an `rmake.rs`. - if cx.config.mode == Mode::RunMake { + if cx.config.mode == TestMode::RunMake { let mut collector = TestCollector::new(); if dir.join("rmake.rs").exists() { let paths = TestPaths { @@ -869,7 +869,7 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te // For run-make tests, each "test file" is actually a _directory_ containing an `rmake.rs`. But // for the purposes of directive parsing, we want to look at that recipe file, not the directory // itself. - let test_path = if cx.config.mode == Mode::RunMake { + let test_path = if cx.config.mode == TestMode::RunMake { testpaths.file.join("rmake.rs") } else { testpaths.file.clone() @@ -884,7 +884,7 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te // - Incremental tests inherently can't run their revisions in parallel, so // we treat them like non-revisioned tests here. Incremental revisions are // handled internally by `runtest::run` instead. - let revisions = if early_props.revisions.is_empty() || cx.config.mode == Mode::Incremental { + let revisions = if early_props.revisions.is_empty() || cx.config.mode == TestMode::Incremental { vec![None] } else { early_props.revisions.iter().map(|r| Some(r.as_str())).collect() @@ -1116,11 +1116,11 @@ fn check_for_overlapping_test_paths(found_path_stems: &HashSet<Utf8PathBuf>) { } pub fn early_config_check(config: &Config) { - if !config.has_html_tidy && config.mode == Mode::Rustdoc { + if !config.has_html_tidy && config.mode == TestMode::Rustdoc { warning!("`tidy` (html-tidy.org) is not installed; diffs will not be generated"); } - if !config.profiler_runtime && config.mode == Mode::CoverageRun { + if !config.profiler_runtime && config.mode == TestMode::CoverageRun { let actioned = if config.bless { "blessed" } else { "checked" }; warning!("profiler runtime is not available, so `.coverage` files won't be {actioned}"); help!("try setting `profiler = true` in the `[build]` section of `bootstrap.toml`"); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 3e879e0e4bb..cb8f593c9df 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -16,11 +16,10 @@ use regex::{Captures, Regex}; use tracing::*; use crate::common::{ - Assembly, Codegen, CodegenUnits, CompareMode, Config, CoverageMap, CoverageRun, Crashes, - DebugInfo, Debugger, FailMode, Incremental, MirOpt, PassMode, Pretty, RunMake, Rustdoc, - RustdocJs, RustdocJson, TestPaths, UI_EXTENSIONS, UI_FIXED, UI_RUN_STDERR, UI_RUN_STDOUT, - UI_STDERR, UI_STDOUT, UI_SVG, UI_WINDOWS_SVG, Ui, expected_output_path, incremental_dir, - output_base_dir, output_base_name, output_testname_unique, + CompareMode, Config, Debugger, FailMode, PassMode, TestMode, TestPaths, TestSuite, + UI_EXTENSIONS, UI_FIXED, UI_RUN_STDERR, UI_RUN_STDOUT, UI_STDERR, UI_STDOUT, UI_SVG, + UI_WINDOWS_SVG, expected_output_path, incremental_dir, output_base_dir, output_base_name, + output_testname_unique, }; use crate::compute_diff::{DiffLine, make_diff, write_diff, write_filtered_diff}; use crate::directives::TestProps; @@ -154,7 +153,7 @@ pub fn run(config: Arc<Config>, testpaths: &TestPaths, revision: Option<&str>) { cx.init_incremental_test(); } - if config.mode == Incremental { + if config.mode == TestMode::Incremental { // Incremental tests are special because they cannot be run in // parallel. assert!(!props.revisions.is_empty(), "Incremental tests require revisions."); @@ -203,7 +202,7 @@ pub fn compute_stamp_hash(config: &Config) -> String { None => {} } - if let Ui = config.mode { + if config.mode == TestMode::Ui { config.force_pass_mode.hash(&mut hash); } @@ -251,25 +250,28 @@ impl<'test> TestCx<'test> { /// Code executed for each revision in turn (or, if there are no /// revisions, exactly once, with revision == None). fn run_revision(&self) { - if self.props.should_ice && self.config.mode != Incremental && self.config.mode != Crashes { + if self.props.should_ice + && self.config.mode != TestMode::Incremental + && self.config.mode != TestMode::Crashes + { self.fatal("cannot use should-ice in a test that is not cfail"); } match self.config.mode { - Pretty => self.run_pretty_test(), - DebugInfo => self.run_debuginfo_test(), - Codegen => self.run_codegen_test(), - Rustdoc => self.run_rustdoc_test(), - RustdocJson => self.run_rustdoc_json_test(), - CodegenUnits => self.run_codegen_units_test(), - Incremental => self.run_incremental_test(), - RunMake => self.run_rmake_test(), - Ui => self.run_ui_test(), - MirOpt => self.run_mir_opt_test(), - Assembly => self.run_assembly_test(), - RustdocJs => self.run_rustdoc_js_test(), - CoverageMap => self.run_coverage_map_test(), // see self::coverage - CoverageRun => self.run_coverage_run_test(), // see self::coverage - Crashes => self.run_crash_test(), + TestMode::Pretty => self.run_pretty_test(), + TestMode::DebugInfo => self.run_debuginfo_test(), + TestMode::Codegen => self.run_codegen_test(), + TestMode::Rustdoc => self.run_rustdoc_test(), + TestMode::RustdocJson => self.run_rustdoc_json_test(), + TestMode::CodegenUnits => self.run_codegen_units_test(), + TestMode::Incremental => self.run_incremental_test(), + TestMode::RunMake => self.run_rmake_test(), + TestMode::Ui => self.run_ui_test(), + TestMode::MirOpt => self.run_mir_opt_test(), + TestMode::Assembly => self.run_assembly_test(), + TestMode::RustdocJs => self.run_rustdoc_js_test(), + TestMode::CoverageMap => self.run_coverage_map_test(), // see self::coverage + TestMode::CoverageRun => self.run_coverage_run_test(), // see self::coverage + TestMode::Crashes => self.run_crash_test(), } } @@ -279,9 +281,13 @@ impl<'test> TestCx<'test> { fn should_run(&self, pm: Option<PassMode>) -> WillExecute { let test_should_run = match self.config.mode { - Ui if pm == Some(PassMode::Run) || self.props.fail_mode == Some(FailMode::Run) => true, - MirOpt if pm == Some(PassMode::Run) => true, - Ui | MirOpt => false, + TestMode::Ui + if pm == Some(PassMode::Run) || self.props.fail_mode == Some(FailMode::Run) => + { + true + } + TestMode::MirOpt if pm == Some(PassMode::Run) => true, + TestMode::Ui | TestMode::MirOpt => false, mode => panic!("unimplemented for mode {:?}", mode), }; if test_should_run { self.run_if_enabled() } else { WillExecute::No } @@ -293,17 +299,17 @@ impl<'test> TestCx<'test> { fn should_run_successfully(&self, pm: Option<PassMode>) -> bool { match self.config.mode { - Ui | MirOpt => pm == Some(PassMode::Run), + TestMode::Ui | TestMode::MirOpt => pm == Some(PassMode::Run), mode => panic!("unimplemented for mode {:?}", mode), } } fn should_compile_successfully(&self, pm: Option<PassMode>) -> bool { match self.config.mode { - RustdocJs => true, - Ui => pm.is_some() || self.props.fail_mode > Some(FailMode::Build), - Crashes => false, - Incremental => { + TestMode::RustdocJs => true, + TestMode::Ui => pm.is_some() || self.props.fail_mode > Some(FailMode::Build), + TestMode::Crashes => false, + TestMode::Incremental => { let revision = self.revision.expect("incremental tests require a list of revisions"); if revision.starts_with("cpass") @@ -349,7 +355,7 @@ impl<'test> TestCx<'test> { if proc_res.status.success() { { self.error(&format!("{} test did not emit an error", self.config.mode)); - if self.config.mode == crate::common::Mode::Ui { + if self.config.mode == crate::common::TestMode::Ui { println!("note: by default, ui tests are expected not to compile"); } proc_res.fatal(None, || ()); @@ -892,7 +898,9 @@ impl<'test> TestCx<'test> { fn should_emit_metadata(&self, pm: Option<PassMode>) -> Emit { match (pm, self.props.fail_mode, self.config.mode) { - (Some(PassMode::Check), ..) | (_, Some(FailMode::Check), Ui) => Emit::Metadata, + (Some(PassMode::Check), ..) | (_, Some(FailMode::Check), TestMode::Ui) => { + Emit::Metadata + } _ => Emit::None, } } @@ -926,7 +934,7 @@ impl<'test> TestCx<'test> { }; let allow_unused = match self.config.mode { - Ui => { + TestMode::Ui => { // UI tests tend to have tons of unused code as // it's just testing various pieces of the compile, but we don't // want to actually assert warnings about all this code. Instead @@ -1021,7 +1029,7 @@ impl<'test> TestCx<'test> { .args(&self.props.compile_flags) .args(&self.props.doc_flags); - if self.config.mode == RustdocJson { + if self.config.mode == TestMode::RustdocJson { rustdoc.arg("--output-format").arg("json").arg("-Zunstable-options"); } @@ -1372,7 +1380,7 @@ impl<'test> TestCx<'test> { || self.is_vxworks_pure_static() || self.config.target.contains("bpf") || !self.config.target_cfg().dynamic_linking - || matches!(self.config.mode, CoverageMap | CoverageRun) + || matches!(self.config.mode, TestMode::CoverageMap | TestMode::CoverageRun) { // We primarily compile all auxiliary libraries as dynamic libraries // to avoid code size bloat and large binaries as much as possible @@ -1486,7 +1494,10 @@ impl<'test> TestCx<'test> { } fn is_rustdoc(&self) -> bool { - matches!(self.config.suite.as_str(), "rustdoc-ui" | "rustdoc-js" | "rustdoc-json") + matches!( + self.config.suite, + TestSuite::RustdocUi | TestSuite::RustdocJs | TestSuite::RustdocJson + ) } fn make_compile_args( @@ -1562,14 +1573,14 @@ impl<'test> TestCx<'test> { rustc.args(&["-Z", "incremental-verify-ich"]); } - if self.config.mode == CodegenUnits { + if self.config.mode == TestMode::CodegenUnits { rustc.args(&["-Z", "human_readable_cgu_names"]); } } if self.config.optimize_tests && !is_rustdoc { match self.config.mode { - Ui => { + TestMode::Ui => { // If optimize-tests is true we still only want to optimize tests that actually get // executed and that don't specify their own optimization levels. // Note: aux libs don't have a pass-mode, so they won't get optimized @@ -1585,8 +1596,8 @@ impl<'test> TestCx<'test> { rustc.arg("-O"); } } - DebugInfo => { /* debuginfo tests must be unoptimized */ } - CoverageMap | CoverageRun => { + TestMode::DebugInfo => { /* debuginfo tests must be unoptimized */ } + TestMode::CoverageMap | TestMode::CoverageRun => { // Coverage mappings and coverage reports are affected by // optimization level, so they ignore the optimize-tests // setting and set an optimization level in their mode's @@ -1607,7 +1618,7 @@ impl<'test> TestCx<'test> { }; match self.config.mode { - Incremental => { + TestMode::Incremental => { // If we are extracting and matching errors in the new // fashion, then you want JSON mode. Old-skool error // patterns still match the raw compiler output. @@ -1620,7 +1631,7 @@ impl<'test> TestCx<'test> { rustc.arg("-Zui-testing"); rustc.arg("-Zdeduplicate-diagnostics=no"); } - Ui => { + TestMode::Ui => { if !self.props.compile_flags.iter().any(|s| s.starts_with("--error-format")) { rustc.args(&["--error-format", "json"]); rustc.args(&["--json", "future-incompat"]); @@ -1633,7 +1644,7 @@ impl<'test> TestCx<'test> { // FIXME: use this for other modes too, for perf? rustc.arg("-Cstrip=debuginfo"); } - MirOpt => { + TestMode::MirOpt => { // We check passes under test to minimize the mir-opt test dump // if files_for_miropt_test parses the passes, we dump only those passes // otherwise we conservatively pass -Zdump-mir=all @@ -1663,7 +1674,7 @@ impl<'test> TestCx<'test> { set_mir_dump_dir(&mut rustc); } - CoverageMap => { + TestMode::CoverageMap => { rustc.arg("-Cinstrument-coverage"); // These tests only compile to LLVM IR, so they don't need the // profiler runtime to be present. @@ -1673,23 +1684,28 @@ impl<'test> TestCx<'test> { // by `compile-flags`. rustc.arg("-Copt-level=2"); } - CoverageRun => { + TestMode::CoverageRun => { rustc.arg("-Cinstrument-coverage"); // Coverage reports are sometimes sensitive to optimizations, // and the current snapshots assume `opt-level=2` unless // overridden by `compile-flags`. rustc.arg("-Copt-level=2"); } - Assembly | Codegen => { + TestMode::Assembly | TestMode::Codegen => { rustc.arg("-Cdebug-assertions=no"); } - Crashes => { + TestMode::Crashes => { set_mir_dump_dir(&mut rustc); } - CodegenUnits => { + TestMode::CodegenUnits => { rustc.arg("-Zprint-mono-items"); } - Pretty | DebugInfo | Rustdoc | RustdocJson | RunMake | RustdocJs => { + TestMode::Pretty + | TestMode::DebugInfo + | TestMode::Rustdoc + | TestMode::RustdocJson + | TestMode::RunMake + | TestMode::RustdocJs => { // do not use JSON output } } @@ -1777,6 +1793,12 @@ impl<'test> TestCx<'test> { // Allow tests to use internal features. rustc.args(&["-A", "internal_features"]); + // Allow tests to have unused parens and braces. + // Add #![deny(unused_parens, unused_braces)] to the test file if you want to + // test that these lints are working. + rustc.args(&["-A", "unused_parens"]); + rustc.args(&["-A", "unused_braces"]); + if self.props.force_host { self.maybe_add_external_args(&mut rustc, &self.config.host_rustcflags); if !is_rustdoc { @@ -1956,7 +1978,7 @@ impl<'test> TestCx<'test> { /// The revision, ignored for incremental compilation since it wants all revisions in /// the same directory. fn safe_revision(&self) -> Option<&str> { - if self.config.mode == Incremental { None } else { self.revision } + if self.config.mode == TestMode::Incremental { None } else { self.revision } } /// Gets the absolute path to the directory where all output for the given diff --git a/src/tools/compiletest/src/runtest/coverage.rs b/src/tools/compiletest/src/runtest/coverage.rs index 38f0e956474..d0a0c960b45 100644 --- a/src/tools/compiletest/src/runtest/coverage.rs +++ b/src/tools/compiletest/src/runtest/coverage.rs @@ -6,7 +6,7 @@ use std::process::Command; use camino::{Utf8Path, Utf8PathBuf}; use glob::glob; -use crate::common::{UI_COVERAGE, UI_COVERAGE_MAP}; +use crate::common::{TestSuite, UI_COVERAGE, UI_COVERAGE_MAP}; use crate::runtest::{Emit, ProcRes, TestCx, WillExecute}; use crate::util::static_regex; @@ -91,7 +91,7 @@ impl<'test> TestCx<'test> { let mut profraw_paths = vec![profraw_path]; let mut bin_paths = vec![self.make_exe_name()]; - if self.config.suite == "coverage-run-rustdoc" { + if self.config.suite == TestSuite::CoverageRunRustdoc { self.run_doctests_for_coverage(&mut profraw_paths, &mut bin_paths); } diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs index 60e8e16e25e..c8d5190c039 100644 --- a/src/tools/compiletest/src/runtest/run_make.rs +++ b/src/tools/compiletest/src/runtest/run_make.rs @@ -225,6 +225,19 @@ impl TestCx<'_> { cmd.env("RUNNER", runner); } + // Guard against externally-set env vars. + cmd.env_remove("__RUSTC_DEBUG_ASSERTIONS_ENABLED"); + if self.config.with_rustc_debug_assertions { + // Used for `run_make_support::env::rustc_debug_assertions_enabled`. + cmd.env("__RUSTC_DEBUG_ASSERTIONS_ENABLED", "1"); + } + + cmd.env_remove("__STD_DEBUG_ASSERTIONS_ENABLED"); + if self.config.with_std_debug_assertions { + // Used for `run_make_support::env::std_debug_assertions_enabled`. + cmd.env("__STD_DEBUG_ASSERTIONS_ENABLED", "1"); + } + // We don't want RUSTFLAGS set from the outside to interfere with // compiler flags set in the test cases: cmd.env_remove("RUSTFLAGS"); diff --git a/src/tools/compiletest/src/runtest/rustdoc.rs b/src/tools/compiletest/src/runtest/rustdoc.rs index 637ea833357..236f021ce82 100644 --- a/src/tools/compiletest/src/runtest/rustdoc.rs +++ b/src/tools/compiletest/src/runtest/rustdoc.rs @@ -4,7 +4,7 @@ use super::{TestCx, remove_and_create_dir_all}; impl TestCx<'_> { pub(super) fn run_rustdoc_test(&self) { - assert!(self.revision.is_none(), "revisions not relevant here"); + assert!(self.revision.is_none(), "revisions not supported in this test suite"); let out_dir = self.output_base_dir(); remove_and_create_dir_all(&out_dir).unwrap_or_else(|e| { diff --git a/src/tools/compiletest/src/runtest/rustdoc_json.rs b/src/tools/compiletest/src/runtest/rustdoc_json.rs index 9f88faca892..4f35efedfde 100644 --- a/src/tools/compiletest/src/runtest/rustdoc_json.rs +++ b/src/tools/compiletest/src/runtest/rustdoc_json.rs @@ -6,7 +6,7 @@ impl TestCx<'_> { pub(super) fn run_rustdoc_json_test(&self) { //FIXME: Add bless option. - assert!(self.revision.is_none(), "revisions not relevant here"); + assert!(self.revision.is_none(), "revisions not supported in this test suite"); let out_dir = self.output_base_dir(); remove_and_create_dir_all(&out_dir).unwrap_or_else(|e| { diff --git a/src/tools/compiletest/src/tests.rs b/src/tools/compiletest/src/tests.rs index e3e4a81755d..174ec9381f6 100644 --- a/src/tools/compiletest/src/tests.rs +++ b/src/tools/compiletest/src/tests.rs @@ -67,11 +67,7 @@ fn is_test_test() { #[test] fn string_enums() { - // These imports are needed for the macro-generated code - use std::fmt; - use std::str::FromStr; - - crate::common::string_enum! { + crate::util::string_enum! { #[derive(Clone, Copy, Debug, PartialEq)] enum Animal { Cat => "meow", diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 202582bea8c..fb047548c45 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -104,3 +104,42 @@ macro_rules! static_regex { }}; } pub(crate) use static_regex; + +macro_rules! string_enum { + ($(#[$meta:meta])* $vis:vis enum $name:ident { $($variant:ident => $repr:expr,)* }) => { + $(#[$meta])* + $vis enum $name { + $($variant,)* + } + + impl $name { + $vis const VARIANTS: &'static [Self] = &[$(Self::$variant,)*]; + $vis const STR_VARIANTS: &'static [&'static str] = &[$(Self::$variant.to_str(),)*]; + + $vis const fn to_str(&self) -> &'static str { + match self { + $(Self::$variant => $repr,)* + } + } + } + + impl ::std::fmt::Display for $name { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::std::fmt::Display::fmt(self.to_str(), f) + } + } + + impl ::std::str::FromStr for $name { + type Err = String; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + match s { + $($repr => Ok(Self::$variant),)* + _ => Err(format!(concat!("unknown `", stringify!($name), "` variant: `{}`"), s)), + } + } + } + } +} + +pub(crate) use string_enum; |
