From fab899640002eb67d9b55156f447bd435f959568 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 7 Aug 2022 21:26:13 -0700 Subject: [PATCH 1/3] compiletest: use precise cfg matching instead of hard-coded tables --- Cargo.lock | 1 + src/tools/compiletest/Cargo.toml | 1 + src/tools/compiletest/src/common.rs | 121 +++++++++++++++++ src/tools/compiletest/src/header.rs | 30 +++- src/tools/compiletest/src/header/tests.rs | 158 ++++++++++++++++++++-- src/tools/compiletest/src/main.rs | 5 +- src/tools/compiletest/src/runtest.rs | 5 +- src/tools/compiletest/src/util.rs | 152 --------------------- src/tools/compiletest/src/util/tests.rs | 37 ----- 9 files changed, 302 insertions(+), 208 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 11d57deb69971..1d2b1e68e1f37 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -816,6 +816,7 @@ dependencies = [ "getopts", "glob", "lazy_static", + "lazycell", "libc", "miow", "regex", diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml index 23e49539969a0..41f97e4326a90 100644 --- a/src/tools/compiletest/Cargo.toml +++ b/src/tools/compiletest/Cargo.toml @@ -17,6 +17,7 @@ rustfix = "0.6.0" lazy_static = "1.0" walkdir = "2" glob = "0.3.0" +lazycell = "1.3.0" [target.'cfg(unix)'.dependencies] libc = "0.2" diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index be81ff881f3a8..470bcc6551f04 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -3,9 +3,11 @@ pub use self::Mode::*; use std::ffi::OsString; use std::fmt; use std::path::{Path, PathBuf}; +use std::process::Command; use std::str::FromStr; use crate::util::PathBufExt; +use lazycell::LazyCell; use test::ColorConfig; #[derive(Clone, Copy, PartialEq, Debug)] @@ -371,6 +373,8 @@ pub struct Config { /// Whether to rerun tests even if the inputs are unchanged. pub force_rerun: bool, + + pub target_cfg: LazyCell, } impl Config { @@ -380,6 +384,123 @@ impl Config { !self.target.ends_with("-fuchsia") }) } + + fn target_cfg(&self) -> &TargetCfg { + self.target_cfg.borrow_with(|| TargetCfg::new(&self.rustc_path, &self.target)) + } + + pub fn matches_arch(&self, arch: &str) -> bool { + self.target_cfg().arch == arch || + // Shorthand for convenience. The arch for + // asmjs-unknown-emscripten is actually wasm32. + (arch == "asmjs" && self.target.starts_with("asmjs")) || + // Matching all the thumb variants as one can be convenient. + // (thumbv6m, thumbv7em, thumbv7m, etc.) + (arch == "thumb" && self.target.starts_with("thumb")) + } + + pub fn matches_os(&self, os: &str) -> bool { + self.target_cfg().os == os + } + + pub fn matches_env(&self, env: &str) -> bool { + self.target_cfg().env == env + } + + pub fn matches_abi(&self, abi: &str) -> bool { + self.target_cfg().abi == abi + } + + pub fn is_big_endian(&self) -> bool { + self.target_cfg().endian == Endian::Big + } + + pub fn get_pointer_width(&self) -> u32 { + *&self.target_cfg().pointer_width + } + + pub fn has_asm_support(&self) -> bool { + static ASM_SUPPORTED_ARCHS: &[&str] = &[ + "x86", "x86_64", "arm", "aarch64", "riscv32", + "riscv64", + // These targets require an additional asm_experimental_arch feature. + // "nvptx64", "hexagon", "mips", "mips64", "spirv", "wasm32", + ]; + ASM_SUPPORTED_ARCHS.contains(&self.target_cfg().arch.as_str()) + } +} + +#[derive(Clone, Debug)] +pub struct TargetCfg { + arch: String, + os: String, + env: String, + abi: String, + pointer_width: u32, + endian: Endian, +} + +#[derive(Eq, PartialEq, Clone, Debug)] +pub enum Endian { + Little, + Big, +} + +impl TargetCfg { + fn new(rustc_path: &Path, target: &str) -> TargetCfg { + let output = match Command::new(rustc_path) + .arg("--print=cfg") + .arg("--target") + .arg(target) + .output() + { + Ok(output) => output, + Err(e) => panic!("error: failed to get cfg info from {:?}: {e}", rustc_path), + }; + if !output.status.success() { + panic!( + "error: failed to get cfg info from {:?}\n--- stdout\n{}\n--- stderr\n{}", + rustc_path, + String::from_utf8(output.stdout).unwrap(), + String::from_utf8(output.stderr).unwrap(), + ); + } + let print_cfg = String::from_utf8(output.stdout).unwrap(); + let mut arch = None; + let mut os = None; + let mut env = None; + let mut abi = None; + let mut pointer_width = None; + let mut endian = None; + for line in print_cfg.lines() { + if let Some((name, value)) = line.split_once('=') { + let value = value.trim_matches('"'); + match name { + "target_arch" => arch = Some(value), + "target_os" => os = Some(value), + "target_env" => env = Some(value), + "target_abi" => abi = Some(value), + "target_pointer_width" => pointer_width = Some(value.parse().unwrap()), + "target_endian" => { + endian = Some(match value { + "little" => Endian::Little, + "big" => Endian::Big, + s => panic!("unexpected {s}"), + }) + } + _ => {} + } + } + } + TargetCfg { + arch: arch.unwrap().to_string(), + os: os.unwrap().to_string(), + env: env.unwrap().to_string(), + abi: abi.unwrap().to_string(), + pointer_width: pointer_width.unwrap(), + endian: endian.unwrap(), + } + } } #[derive(Debug, Clone)] diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index f8f193ddf83fb..c50dd3cc09df5 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -661,17 +661,35 @@ impl Config { let name = line[prefix.len() + 1..].split(&[':', ' '][..]).next().unwrap(); + let matches_pointer_width = || { + name.strip_suffix("bit") + .and_then(|width| width.parse::().ok()) + .map(|width| self.get_pointer_width() == width) + .unwrap_or(false) + }; + + // If something is ignored for emscripten, it likely also needs to be + // ignored for wasm32-unknown-unknown. + // `wasm32-bare` is an alias to refer to just wasm32-unknown-unknown + // (in contrast to `wasm32` which also matches non-bare targets like + // asmjs-unknown-emscripten). + let matches_wasm32_alias = || { + self.target == "wasm32-unknown-unknown" && matches!(name, "emscripten" | "wasm32-bare") + }; + let is_match = name == "test" || self.target == name || // triple - util::matches_os(&self.target, name) || // target - util::matches_env(&self.target, name) || // env + self.matches_os(name) || + self.matches_env(name) || + self.matches_abi(name) || self.target.ends_with(name) || // target and env - name == util::get_arch(&self.target) || // architecture - name == util::get_pointer_width(&self.target) || // pointer width + self.matches_arch(name) || + matches_wasm32_alias() || + matches_pointer_width() || name == self.stage_id.split('-').next().unwrap() || // stage name == self.channel || // channel (self.target != self.host && name == "cross-compile") || - (name == "endian-big" && util::is_big_endian(&self.target)) || + (name == "endian-big" && self.is_big_endian()) || (self.remote_test_client.is_some() && name == "remote") || match self.compare_mode { Some(CompareMode::Polonius) => name == "compare-mode-polonius", @@ -869,7 +887,7 @@ pub fn make_test_description( let rustc_has_profiler_support = env::var_os("RUSTC_PROFILER_SUPPORT").is_some(); let rustc_has_sanitizer_support = env::var_os("RUSTC_SANITIZER_SUPPORT").is_some(); - let has_asm_support = util::has_asm_support(&config.target); + let has_asm_support = config.has_asm_support(); let has_asan = util::ASAN_SUPPORTED_TARGETS.contains(&&*config.target); let has_cfi = util::CFI_SUPPORTED_TARGETS.contains(&&*config.target); let has_lsan = util::LSAN_SUPPORTED_TARGETS.contains(&&*config.target); diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index a8fd4880f0782..21523cc13e6fc 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -42,7 +42,6 @@ fn config() -> Config { "--suite=ui", "--compile-lib-path=", "--run-lib-path=", - "--rustc-path=", "--python=", "--jsondocck-path=", "--src-base=", @@ -57,7 +56,9 @@ fn config() -> Config { "--target=x86_64-unknown-linux-gnu", "--channel=nightly", ]; - let args = args.iter().map(ToString::to_string).collect(); + let mut args: Vec = args.iter().map(ToString::to_string).collect(); + args.push("--rustc-path".to_string()); + args.push(std::env::var("RUSTC").unwrap_or_else(|_| "rustc".to_string())); crate::parse_config(args) } @@ -237,13 +238,20 @@ fn sanitizers() { #[test] fn asm_support() { - let mut config = config(); - - config.target = "avr-unknown-gnu-atmega328".to_owned(); - assert!(check_ignore(&config, "// needs-asm-support")); - - config.target = "i686-unknown-netbsd".to_owned(); - assert!(!check_ignore(&config, "// needs-asm-support")); + let asms = [ + ("avr-unknown-gnu-atmega328", false), + ("i686-unknown-netbsd", true), + ("riscv32gc-unknown-linux-gnu", true), + ("riscv64imac-unknown-none-elf", true), + ("x86_64-unknown-linux-gnu", true), + ("i686-unknown-netbsd", true), + ]; + for (target, has_asm) in asms { + let mut config = config(); + config.target = target.to_string(); + assert_eq!(config.has_asm_support(), has_asm); + assert_eq!(check_ignore(&config, "// needs-asm-support"), !has_asm) + } } #[test] @@ -281,3 +289,135 @@ fn test_duplicate_revisions() { let config = config(); parse_rs(&config, "// revisions: rpass1 rpass1"); } + +#[test] +fn ignore_arch() { + let archs = [ + ("x86_64-unknown-linux-gnu", "x86_64"), + ("i686-unknown-linux-gnu", "x86"), + ("nvptx64-nvidia-cuda", "nvptx64"), + ("asmjs-unknown-emscripten", "wasm32"), + ("asmjs-unknown-emscripten", "asmjs"), + ("thumbv7m-none-eabi", "thumb"), + ]; + for (target, arch) in archs { + let mut config = config(); + config.target = target.to_string(); + assert!(config.matches_arch(arch), "{target} {arch}"); + assert!(check_ignore(&config, &format!("// ignore-{arch}"))); + } +} + +#[test] +fn matches_os() { + let oss = [ + ("x86_64-unknown-linux-gnu", "linux"), + ("x86_64-fortanix-unknown-sgx", "unknown"), + ("wasm32-unknown-unknown", "unknown"), + ("x86_64-unknown-none", "none"), + ]; + for (target, os) in oss { + let mut config = config(); + config.target = target.to_string(); + assert!(config.matches_os(os), "{target} {os}"); + assert!(check_ignore(&config, &format!("// ignore-{os}"))); + } +} + +#[test] +fn matches_env() { + let envs = [ + ("x86_64-unknown-linux-gnu", "gnu"), + ("x86_64-fortanix-unknown-sgx", "sgx"), + ("arm-unknown-linux-musleabi", "musl"), + ]; + for (target, env) in envs { + let mut config = config(); + config.target = target.to_string(); + assert!(config.matches_env(env), "{target} {env}"); + assert!(check_ignore(&config, &format!("// ignore-{env}"))); + } +} + +#[test] +fn matches_abi() { + let abis = [ + ("aarch64-apple-ios-macabi", "macabi"), + ("x86_64-unknown-linux-gnux32", "x32"), + ("arm-unknown-linux-gnueabi", "eabi"), + ]; + for (target, abi) in abis { + let mut config = config(); + config.target = target.to_string(); + assert!(config.matches_abi(abi), "{target} {abi}"); + assert!(check_ignore(&config, &format!("// ignore-{abi}"))); + } +} + +#[test] +fn is_big_endian() { + let endians = [ + ("x86_64-unknown-linux-gnu", false), + ("bpfeb-unknown-none", true), + ("m68k-unknown-linux-gnu", true), + ("aarch64_be-unknown-linux-gnu", true), + ("powerpc64-unknown-linux-gnu", true), + ]; + for (target, is_big) in endians { + let mut config = config(); + config.target = target.to_string(); + assert_eq!(config.is_big_endian(), is_big, "{target} {is_big}"); + assert_eq!(check_ignore(&config, "// ignore-endian-big"), is_big); + } +} + +#[test] +fn pointer_width() { + let widths = [ + ("x86_64-unknown-linux-gnu", 64), + ("i686-unknown-linux-gnu", 32), + ("arm64_32-apple-watchos", 32), + ("msp430-none-elf", 16), + ]; + for (target, width) in widths { + let mut config = config(); + config.target = target.to_string(); + assert_eq!(config.get_pointer_width(), width, "{target} {width}"); + assert_eq!(check_ignore(&config, "// ignore-16bit"), width == 16); + assert_eq!(check_ignore(&config, "// ignore-32bit"), width == 32); + assert_eq!(check_ignore(&config, "// ignore-64bit"), width == 64); + } +} + +#[test] +fn wasm_special() { + let ignores = [ + ("wasm32-unknown-unknown", "emscripten", true), + ("wasm32-unknown-unknown", "wasm32", true), + ("wasm32-unknown-unknown", "wasm32-bare", true), + ("wasm32-unknown-unknown", "wasm64", false), + ("asmjs-unknown-emscripten", "emscripten", true), + ("asmjs-unknown-emscripten", "wasm32", true), + ("asmjs-unknown-emscripten", "wasm32-bare", false), + ("wasm32-unknown-emscripten", "emscripten", true), + ("wasm32-unknown-emscripten", "wasm32", true), + ("wasm32-unknown-emscripten", "wasm32-bare", false), + ("wasm32-wasi", "emscripten", false), + ("wasm32-wasi", "wasm32", true), + ("wasm32-wasi", "wasm32-bare", false), + ("wasm32-wasi", "wasi", true), + ("wasm64-unknown-unknown", "emscripten", false), + ("wasm64-unknown-unknown", "wasm32", false), + ("wasm64-unknown-unknown", "wasm32-bare", false), + ("wasm64-unknown-unknown", "wasm64", true), + ]; + for (target, pattern, ignore) in ignores { + let mut config = config(); + config.target = target.to_string(); + assert_eq!( + check_ignore(&config, &format!("// ignore-{pattern}")), + ignore, + "{target} {pattern}" + ); + } +} diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index a8a151ca114d2..ac6d80bb439b3 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -11,6 +11,7 @@ use crate::common::{ use crate::common::{CompareMode, Config, Debugger, Mode, PassMode, TestPaths}; use crate::util::logv; use getopts::Options; +use lazycell::LazyCell; use std::env; use std::ffi::OsString; use std::fs; @@ -299,6 +300,8 @@ pub fn parse_config(args: Vec) -> Config { npm: matches.opt_str("npm"), force_rerun: matches.opt_present("force-rerun"), + + target_cfg: LazyCell::new(), } } @@ -441,7 +444,7 @@ fn configure_cdb(config: &Config) -> Option { fn configure_gdb(config: &Config) -> Option { config.gdb_version?; - if util::matches_env(&config.target, "msvc") { + if config.matches_env("msvc") { return None; } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index d3e5a2dd644af..47f2a2d34821c 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -13,7 +13,6 @@ use crate::errors::{self, Error, ErrorKind}; use crate::header::TestProps; use crate::json; use crate::read2::read2_abbreviated; -use crate::util::get_pointer_width; use crate::util::{logv, PathBufExt}; use crate::ColorConfig; use regex::{Captures, Regex}; @@ -3127,7 +3126,7 @@ impl<'test> TestCx<'test> { output_kind: TestOutput, explicit_format: bool, ) -> usize { - let stderr_bits = format!("{}.stderr", get_pointer_width(&self.config.target)); + let stderr_bits = format!("{}bit.stderr", self.config.get_pointer_width()); let (stderr_kind, stdout_kind) = match output_kind { TestOutput::Compile => ( { @@ -3402,7 +3401,7 @@ impl<'test> TestCx<'test> { let mut bit_width = String::new(); if test_file_contents.lines().any(|l| l == "// EMIT_MIR_FOR_EACH_BIT_WIDTH") { - bit_width = format!(".{}", get_pointer_width(&self.config.target)); + bit_width = format!(".{}bit", self.config.get_pointer_width()); } if self.config.bless { diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 22df18ee9fbb8..9d047b63c8593 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -8,84 +8,6 @@ use tracing::*; #[cfg(test)] mod tests; -/// Conversion table from triple OS name to Rust SYSNAME -const OS_TABLE: &[(&str, &str)] = &[ - ("android", "android"), - ("androideabi", "android"), - ("cuda", "cuda"), - ("darwin", "macos"), - ("dragonfly", "dragonfly"), - ("emscripten", "emscripten"), - ("freebsd", "freebsd"), - ("fuchsia", "fuchsia"), - ("haiku", "haiku"), - ("hermit", "hermit"), - ("illumos", "illumos"), - ("ios", "ios"), - ("l4re", "l4re"), - ("linux", "linux"), - ("mingw32", "windows"), - ("none", "none"), - ("netbsd", "netbsd"), - ("openbsd", "openbsd"), - ("redox", "redox"), - ("sgx", "sgx"), - ("solaris", "solaris"), - ("watchos", "watchos"), - ("win32", "windows"), - ("windows", "windows"), - ("vxworks", "vxworks"), -]; - -const ARCH_TABLE: &[(&str, &str)] = &[ - ("aarch64", "aarch64"), - ("aarch64_be", "aarch64"), - ("amd64", "x86_64"), - ("arm", "arm"), - ("arm64", "aarch64"), - ("armv4t", "arm"), - ("armv5te", "arm"), - ("armv7", "arm"), - ("armv7s", "arm"), - ("asmjs", "asmjs"), - ("avr", "avr"), - ("bpfeb", "bpf"), - ("bpfel", "bpf"), - ("hexagon", "hexagon"), - ("i386", "x86"), - ("i586", "x86"), - ("i686", "x86"), - ("m68k", "m68k"), - ("mips", "mips"), - ("mips64", "mips64"), - ("mips64el", "mips64"), - ("mipsisa32r6", "mips"), - ("mipsisa32r6el", "mips"), - ("mipsisa64r6", "mips64"), - ("mipsisa64r6el", "mips64"), - ("mipsel", "mips"), - ("mipsisa32r6", "mips"), - ("mipsisa32r6el", "mips"), - ("mipsisa64r6", "mips64"), - ("mipsisa64r6el", "mips64"), - ("msp430", "msp430"), - ("nvptx64", "nvptx64"), - ("powerpc", "powerpc"), - ("powerpc64", "powerpc64"), - ("powerpc64le", "powerpc64"), - ("riscv64gc", "riscv64"), - ("s390x", "s390x"), - ("sparc", "sparc"), - ("sparc64", "sparc64"), - ("sparcv9", "sparc64"), - ("thumbv6m", "thumb"), - ("thumbv7em", "thumb"), - ("thumbv7m", "thumb"), - ("wasm32", "wasm32"), - ("x86_64", "x86_64"), - ("xcore", "xcore"), -]; - pub const ASAN_SUPPORTED_TARGETS: &[&str] = &[ "aarch64-apple-darwin", "aarch64-fuchsia", @@ -140,80 +62,6 @@ pub const MEMTAG_SUPPORTED_TARGETS: &[&str] = pub const SHADOWCALLSTACK_SUPPORTED_TARGETS: &[&str] = &["aarch64-linux-android"]; -const BIG_ENDIAN: &[&str] = &[ - "aarch64_be", - "armebv7r", - "mips", - "mips64", - "mipsisa32r6", - "mipsisa64r6", - "powerpc", - "powerpc64", - "s390x", - "sparc", - "sparc64", - "sparcv9", -]; - -static ASM_SUPPORTED_ARCHS: &[&str] = &[ - "x86", "x86_64", "arm", "aarch64", "riscv32", - "riscv64", - // These targets require an additional asm_experimental_arch feature. - // "nvptx64", "hexagon", "mips", "mips64", "spirv", "wasm32", -]; - -pub fn has_asm_support(triple: &str) -> bool { - ASM_SUPPORTED_ARCHS.contains(&get_arch(triple)) -} - -pub fn matches_os(triple: &str, name: &str) -> bool { - // For the wasm32 bare target we ignore anything also ignored on emscripten - // and then we also recognize `wasm32-bare` as the os for the target - if triple == "wasm32-unknown-unknown" { - return name == "emscripten" || name == "wasm32-bare"; - } - let triple: Vec<_> = triple.split('-').collect(); - for &(triple_os, os) in OS_TABLE { - if triple.contains(&triple_os) { - return os == name; - } - } - panic!("Cannot determine OS from triple"); -} - -/// Determine the architecture from `triple` -pub fn get_arch(triple: &str) -> &'static str { - let triple: Vec<_> = triple.split('-').collect(); - for &(triple_arch, arch) in ARCH_TABLE { - if triple.contains(&triple_arch) { - return arch; - } - } - panic!("Cannot determine Architecture from triple"); -} - -/// Determine the endianness from `triple` -pub fn is_big_endian(triple: &str) -> bool { - let triple_arch = triple.split('-').next().unwrap(); - BIG_ENDIAN.contains(&triple_arch) -} - -pub fn matches_env(triple: &str, name: &str) -> bool { - if let Some(env) = triple.split('-').nth(3) { env.starts_with(name) } else { false } -} - -pub fn get_pointer_width(triple: &str) -> &'static str { - if (triple.contains("64") && !triple.ends_with("gnux32") && !triple.ends_with("gnu_ilp32")) - || triple.starts_with("s390x") - { - "64bit" - } else if triple.starts_with("avr") { - "16bit" - } else { - "32bit" - } -} - pub fn make_new_path(path: &str) -> String { assert!(cfg!(windows)); // Windows just uses PATH as the library search path, so we have to diff --git a/src/tools/compiletest/src/util/tests.rs b/src/tools/compiletest/src/util/tests.rs index 663027173ff9d..b09a183b14e6a 100644 --- a/src/tools/compiletest/src/util/tests.rs +++ b/src/tools/compiletest/src/util/tests.rs @@ -1,42 +1,5 @@ use super::*; -#[test] -#[should_panic(expected = "Cannot determine Architecture from triple")] -fn test_get_arch_failure() { - get_arch("abc"); -} - -#[test] -fn test_get_arch() { - assert_eq!("x86_64", get_arch("x86_64-unknown-linux-gnu")); - assert_eq!("x86_64", get_arch("amd64")); - assert_eq!("nvptx64", get_arch("nvptx64-nvidia-cuda")); -} - -#[test] -#[should_panic(expected = "Cannot determine OS from triple")] -fn test_matches_os_failure() { - matches_os("abc", "abc"); -} - -#[test] -fn test_matches_os() { - assert!(matches_os("x86_64-unknown-linux-gnu", "linux")); - assert!(matches_os("wasm32-unknown-unknown", "emscripten")); - assert!(matches_os("wasm32-unknown-unknown", "wasm32-bare")); - assert!(!matches_os("wasm32-unknown-unknown", "windows")); - assert!(matches_os("thumbv6m0-none-eabi", "none")); - assert!(matches_os("riscv32imc-unknown-none-elf", "none")); - assert!(matches_os("nvptx64-nvidia-cuda", "cuda")); - assert!(matches_os("x86_64-fortanix-unknown-sgx", "sgx")); -} - -#[test] -fn is_big_endian_test() { - assert!(!is_big_endian("no")); - assert!(is_big_endian("sparc-unknown-unknown")); -} - #[test] fn path_buf_with_extra_extension_test() { assert_eq!( From c86e523d97104d508b98747079f12edd3b53a672 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 7 Aug 2022 21:44:23 -0700 Subject: [PATCH 2/3] compiletest: match ignores on target family This primarily is so that `ignore-wasm` works as expected (ignores all wasm-like targets). --- src/tools/compiletest/src/common.rs | 8 ++++++++ src/tools/compiletest/src/header.rs | 1 + src/tools/compiletest/src/header/tests.rs | 20 ++++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 470bcc6551f04..6f17b9e1be9a3 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -411,6 +411,10 @@ impl Config { self.target_cfg().abi == abi } + pub fn matches_family(&self, family: &str) -> bool { + self.target_cfg().families.iter().any(|f| f == family) + } + pub fn is_big_endian(&self) -> bool { self.target_cfg().endian == Endian::Big } @@ -436,6 +440,7 @@ pub struct TargetCfg { os: String, env: String, abi: String, + families: Vec, pointer_width: u32, endian: Endian, } @@ -470,6 +475,7 @@ impl TargetCfg { let mut os = None; let mut env = None; let mut abi = None; + let mut families = Vec::new(); let mut pointer_width = None; let mut endian = None; for line in print_cfg.lines() { @@ -480,6 +486,7 @@ impl TargetCfg { "target_os" => os = Some(value), "target_env" => env = Some(value), "target_abi" => abi = Some(value), + "target_family" => families.push(value.to_string()), "target_pointer_width" => pointer_width = Some(value.parse().unwrap()), "target_endian" => { endian = Some(match value { @@ -497,6 +504,7 @@ impl TargetCfg { os: os.unwrap().to_string(), env: env.unwrap().to_string(), abi: abi.unwrap().to_string(), + families, pointer_width: pointer_width.unwrap(), endian: endian.unwrap(), } diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index c50dd3cc09df5..8f097f47b451a 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -682,6 +682,7 @@ impl Config { self.matches_os(name) || self.matches_env(name) || self.matches_abi(name) || + self.matches_family(name) || self.target.ends_with(name) || // target and env self.matches_arch(name) || matches_wasm32_alias() || diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index 21523cc13e6fc..6c0e8f2e46f72 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -421,3 +421,23 @@ fn wasm_special() { ); } } + +#[test] +fn families() { + let families = [ + ("x86_64-unknown-linux-gnu", "unix"), + ("x86_64-pc-windows-gnu", "windows"), + ("wasm32-unknown-unknown", "wasm"), + ("wasm32-unknown-emscripten", "wasm"), + ("wasm32-unknown-emscripten", "unix"), + ]; + for (target, family) in families { + let mut config = config(); + config.target = target.to_string(); + assert!(config.matches_family(family)); + let other = if family == "windows" { "unix" } else { "windows" }; + assert!(!config.matches_family(other)); + assert!(check_ignore(&config, &format!("// ignore-{family}"))); + assert!(!check_ignore(&config, &format!("// ignore-{other}"))); + } +} From 2462bd17a029e8333796bb7190bce4bdfc4da91b Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 8 Aug 2022 22:51:16 -0700 Subject: [PATCH 3/3] compiletest: Add warning and comment about running tests without RUSTC --- src/tools/compiletest/src/header/tests.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index 6c0e8f2e46f72..bcd222b5a9322 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -58,7 +58,22 @@ fn config() -> Config { ]; let mut args: Vec = args.iter().map(ToString::to_string).collect(); args.push("--rustc-path".to_string()); - args.push(std::env::var("RUSTC").unwrap_or_else(|_| "rustc".to_string())); + // This is a subtle/fragile thing. On rust-lang CI, there is no global + // `rustc`, and Cargo doesn't offer a convenient way to get the path to + // `rustc`. Fortunately bootstrap sets `RUSTC` for us, which is pointing + // to the stage0 compiler. + // + // Otherwise, if you are running compiletests's tests manually, you + // probably don't have `RUSTC` set, in which case this falls back to the + // global rustc. If your global rustc is too far out of sync with stage0, + // then this may cause confusing errors. Or if for some reason you don't + // have rustc in PATH, that would also fail. + args.push(std::env::var("RUSTC").unwrap_or_else(|_| { + eprintln!( + "warning: RUSTC not set, using global rustc (are you not running via bootstrap?)" + ); + "rustc".to_string() + })); crate::parse_config(args) }