mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Auto merge of #108905 - ferrocene:pa-compiletest-ignore, r=ehuss
Validate `ignore` and `only` compiletest directive, and add human-readable ignore reasons This PR adds strict validation for the `ignore` and `only` compiletest directives, failing if an unknown value is provided to them. Doing so uncovered 79 tests in `tests/ui` that had invalid directives, so this PR also fixes them. Finally, this PR adds human-readable ignore reasons when tests are ignored due to `ignore` or `only` directives, like *"only executed when the architecture is aarch64"* or *"ignored when the operative system is windows"*. This was the original reason why I started working on this PR and #108659, as we need both of them for Ferrocene. The PR is a draft because the code is extremely inefficient: it calls `rustc --print=cfg --target $target` for every rustc target (to gather the list of allowed ignore values), which on my system takes between 4s and 5s, and performs a lot of allocations of constant values. I'll fix both of them in the coming days. r? `@ehuss`
This commit is contained in:
commit
b2b676d886
@ -44,8 +44,10 @@ use rustc_session::{early_error, early_error_no_abort, early_warn};
|
||||
use rustc_span::source_map::{FileLoader, FileName};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_target::json::ToJson;
|
||||
use rustc_target::spec::{Target, TargetTriple};
|
||||
|
||||
use std::cmp::max;
|
||||
use std::collections::BTreeMap;
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::fs;
|
||||
@ -648,6 +650,15 @@ fn print_crate_info(
|
||||
TargetSpec => {
|
||||
println!("{}", serde_json::to_string_pretty(&sess.target.to_json()).unwrap());
|
||||
}
|
||||
AllTargetSpecs => {
|
||||
let mut targets = BTreeMap::new();
|
||||
for name in rustc_target::spec::TARGETS {
|
||||
let triple = TargetTriple::from_triple(name);
|
||||
let target = Target::expect_builtin(&triple);
|
||||
targets.insert(name, target.to_json());
|
||||
}
|
||||
println!("{}", serde_json::to_string_pretty(&targets).unwrap());
|
||||
}
|
||||
FileNames | CrateName => {
|
||||
let Some(attrs) = attrs.as_ref() else {
|
||||
// no crate attributes, print out an error and exit
|
||||
|
@ -582,6 +582,7 @@ pub enum PrintRequest {
|
||||
CodeModels,
|
||||
TlsModels,
|
||||
TargetSpec,
|
||||
AllTargetSpecs,
|
||||
NativeStaticLibs,
|
||||
StackProtectorStrategies,
|
||||
LinkArgs,
|
||||
@ -1441,8 +1442,8 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
|
||||
"Compiler information to print on stdout",
|
||||
"[crate-name|file-names|sysroot|target-libdir|cfg|calling-conventions|\
|
||||
target-list|target-cpus|target-features|relocation-models|code-models|\
|
||||
tls-models|target-spec-json|native-static-libs|stack-protector-strategies|\
|
||||
link-args]",
|
||||
tls-models|target-spec-json|all-target-specs-json|native-static-libs|\
|
||||
stack-protector-strategies|link-args]",
|
||||
),
|
||||
opt::flagmulti_s("g", "", "Equivalent to -C debuginfo=2"),
|
||||
opt::flagmulti_s("O", "", "Equivalent to -C opt-level=2"),
|
||||
@ -1889,6 +1890,7 @@ fn collect_print_requests(
|
||||
("native-static-libs", PrintRequest::NativeStaticLibs),
|
||||
("stack-protector-strategies", PrintRequest::StackProtectorStrategies),
|
||||
("target-spec-json", PrintRequest::TargetSpec),
|
||||
("all-target-specs-json", PrintRequest::AllTargetSpecs),
|
||||
("link-args", PrintRequest::LinkArgs),
|
||||
("split-debuginfo", PrintRequest::SplitDebuginfo),
|
||||
];
|
||||
@ -1902,7 +1904,18 @@ fn collect_print_requests(
|
||||
early_error(
|
||||
error_format,
|
||||
"the `-Z unstable-options` flag must also be passed to \
|
||||
enable the target-spec-json print option",
|
||||
enable the target-spec-json print option",
|
||||
);
|
||||
}
|
||||
}
|
||||
Some((_, PrintRequest::AllTargetSpecs)) => {
|
||||
if unstable_opts.unstable_options {
|
||||
PrintRequest::AllTargetSpecs
|
||||
} else {
|
||||
early_error(
|
||||
error_format,
|
||||
"the `-Z unstable-options` flag must also be passed to \
|
||||
enable the all-target-specs-json print option",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -694,7 +694,7 @@ impl Step for CompiletestTest {
|
||||
/// Runs `cargo test` for compiletest.
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
let host = self.host;
|
||||
let compiler = builder.compiler(0, host);
|
||||
let compiler = builder.compiler(1, host);
|
||||
|
||||
// We need `ToolStd` for the locally-built sysroot because
|
||||
// compiletest uses unstable features of the `test` crate.
|
||||
|
@ -8,24 +8,65 @@ use std::process::Command;
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::util::{add_dylib_path, PathBufExt};
|
||||
use lazycell::LazyCell;
|
||||
use lazycell::AtomicLazyCell;
|
||||
use serde::de::{Deserialize, Deserializer, Error as _};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use test::{ColorConfig, OutputFormat};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
pub enum Mode {
|
||||
RunPassValgrind,
|
||||
Pretty,
|
||||
DebugInfo,
|
||||
Codegen,
|
||||
Rustdoc,
|
||||
RustdocJson,
|
||||
CodegenUnits,
|
||||
Incremental,
|
||||
RunMake,
|
||||
Ui,
|
||||
JsDocTest,
|
||||
MirOpt,
|
||||
Assembly,
|
||||
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 = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, ()> {
|
||||
match s {
|
||||
$($repr => Ok(Self::$variant),)*
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string_enum! {
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
pub enum Mode {
|
||||
RunPassValgrind => "run-pass-valgrind",
|
||||
Pretty => "pretty",
|
||||
DebugInfo => "debuginfo",
|
||||
Codegen => "codegen",
|
||||
Rustdoc => "rustdoc",
|
||||
RustdocJson => "rustdoc-json",
|
||||
CodegenUnits => "codegen-units",
|
||||
Incremental => "incremental",
|
||||
RunMake => "run-make",
|
||||
Ui => "ui",
|
||||
JsDocTest => "js-doc-test",
|
||||
MirOpt => "mir-opt",
|
||||
Assembly => "assembly",
|
||||
}
|
||||
}
|
||||
|
||||
impl Mode {
|
||||
@ -39,76 +80,12 @@ impl Mode {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Mode {
|
||||
type Err = ();
|
||||
fn from_str(s: &str) -> Result<Mode, ()> {
|
||||
match s {
|
||||
"run-pass-valgrind" => Ok(RunPassValgrind),
|
||||
"pretty" => Ok(Pretty),
|
||||
"debuginfo" => Ok(DebugInfo),
|
||||
"codegen" => Ok(Codegen),
|
||||
"rustdoc" => Ok(Rustdoc),
|
||||
"rustdoc-json" => Ok(RustdocJson),
|
||||
"codegen-units" => Ok(CodegenUnits),
|
||||
"incremental" => Ok(Incremental),
|
||||
"run-make" => Ok(RunMake),
|
||||
"ui" => Ok(Ui),
|
||||
"js-doc-test" => Ok(JsDocTest),
|
||||
"mir-opt" => Ok(MirOpt),
|
||||
"assembly" => Ok(Assembly),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Mode {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let s = match *self {
|
||||
RunPassValgrind => "run-pass-valgrind",
|
||||
Pretty => "pretty",
|
||||
DebugInfo => "debuginfo",
|
||||
Codegen => "codegen",
|
||||
Rustdoc => "rustdoc",
|
||||
RustdocJson => "rustdoc-json",
|
||||
CodegenUnits => "codegen-units",
|
||||
Incremental => "incremental",
|
||||
RunMake => "run-make",
|
||||
Ui => "ui",
|
||||
JsDocTest => "js-doc-test",
|
||||
MirOpt => "mir-opt",
|
||||
Assembly => "assembly",
|
||||
};
|
||||
fmt::Display::fmt(s, f)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Debug, Hash)]
|
||||
pub enum PassMode {
|
||||
Check,
|
||||
Build,
|
||||
Run,
|
||||
}
|
||||
|
||||
impl FromStr for PassMode {
|
||||
type Err = ();
|
||||
fn from_str(s: &str) -> Result<Self, ()> {
|
||||
match s {
|
||||
"check" => Ok(PassMode::Check),
|
||||
"build" => Ok(PassMode::Build),
|
||||
"run" => Ok(PassMode::Run),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for PassMode {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let s = match *self {
|
||||
PassMode::Check => "check",
|
||||
PassMode::Build => "build",
|
||||
PassMode::Run => "run",
|
||||
};
|
||||
fmt::Display::fmt(s, f)
|
||||
string_enum! {
|
||||
#[derive(Clone, Copy, PartialEq, Debug, Hash)]
|
||||
pub enum PassMode {
|
||||
Check => "check",
|
||||
Build => "build",
|
||||
Run => "run",
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,63 +96,30 @@ pub enum FailMode {
|
||||
Run,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum CompareMode {
|
||||
Polonius,
|
||||
Chalk,
|
||||
NextSolver,
|
||||
SplitDwarf,
|
||||
SplitDwarfSingle,
|
||||
}
|
||||
|
||||
impl CompareMode {
|
||||
pub(crate) fn to_str(&self) -> &'static str {
|
||||
match *self {
|
||||
CompareMode::Polonius => "polonius",
|
||||
CompareMode::Chalk => "chalk",
|
||||
CompareMode::NextSolver => "next-solver",
|
||||
CompareMode::SplitDwarf => "split-dwarf",
|
||||
CompareMode::SplitDwarfSingle => "split-dwarf-single",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(s: String) -> CompareMode {
|
||||
match s.as_str() {
|
||||
"polonius" => CompareMode::Polonius,
|
||||
"chalk" => CompareMode::Chalk,
|
||||
"next-solver" => CompareMode::NextSolver,
|
||||
"split-dwarf" => CompareMode::SplitDwarf,
|
||||
"split-dwarf-single" => CompareMode::SplitDwarfSingle,
|
||||
x => panic!("unknown --compare-mode option: {}", x),
|
||||
}
|
||||
string_enum! {
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum CompareMode {
|
||||
Polonius => "polonius",
|
||||
Chalk => "chalk",
|
||||
NextSolver => "next-solver",
|
||||
SplitDwarf => "split-dwarf",
|
||||
SplitDwarfSingle => "split-dwarf-single",
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum Debugger {
|
||||
Cdb,
|
||||
Gdb,
|
||||
Lldb,
|
||||
}
|
||||
|
||||
impl Debugger {
|
||||
fn to_str(&self) -> &'static str {
|
||||
match self {
|
||||
Debugger::Cdb => "cdb",
|
||||
Debugger::Gdb => "gdb",
|
||||
Debugger::Lldb => "lldb",
|
||||
}
|
||||
string_enum! {
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum Debugger {
|
||||
Cdb => "cdb",
|
||||
Gdb => "gdb",
|
||||
Lldb => "lldb",
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Debugger {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Display::fmt(self.to_str(), f)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Default, serde::Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum PanicStrategy {
|
||||
#[default]
|
||||
Unwind,
|
||||
Abort,
|
||||
}
|
||||
@ -383,7 +327,7 @@ pub struct Config {
|
||||
/// Only rerun the tests that result has been modified accoring to Git status
|
||||
pub only_modified: bool,
|
||||
|
||||
pub target_cfg: LazyCell<TargetCfg>,
|
||||
pub target_cfgs: AtomicLazyCell<TargetCfgs>,
|
||||
|
||||
pub nocapture: bool,
|
||||
}
|
||||
@ -396,8 +340,18 @@ impl Config {
|
||||
})
|
||||
}
|
||||
|
||||
fn target_cfg(&self) -> &TargetCfg {
|
||||
self.target_cfg.borrow_with(|| TargetCfg::new(self))
|
||||
pub fn target_cfgs(&self) -> &TargetCfgs {
|
||||
match self.target_cfgs.borrow() {
|
||||
Some(cfgs) => cfgs,
|
||||
None => {
|
||||
let _ = self.target_cfgs.fill(TargetCfgs::new(self));
|
||||
self.target_cfgs.borrow().unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn target_cfg(&self) -> &TargetCfg {
|
||||
&self.target_cfgs().current
|
||||
}
|
||||
|
||||
pub fn matches_arch(&self, arch: &str) -> bool {
|
||||
@ -449,94 +403,154 @@ impl Config {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TargetCfgs {
|
||||
pub current: TargetCfg,
|
||||
pub all_targets: HashSet<String>,
|
||||
pub all_archs: HashSet<String>,
|
||||
pub all_oses: HashSet<String>,
|
||||
pub all_oses_and_envs: HashSet<String>,
|
||||
pub all_envs: HashSet<String>,
|
||||
pub all_abis: HashSet<String>,
|
||||
pub all_families: HashSet<String>,
|
||||
pub all_pointer_widths: HashSet<String>,
|
||||
}
|
||||
|
||||
impl TargetCfgs {
|
||||
fn new(config: &Config) -> TargetCfgs {
|
||||
let targets: HashMap<String, TargetCfg> = if config.stage_id.starts_with("stage0-") {
|
||||
// #[cfg(bootstrap)]
|
||||
// Needed only for one cycle, remove during the bootstrap bump.
|
||||
Self::collect_all_slow(config)
|
||||
} else {
|
||||
serde_json::from_str(&rustc_output(
|
||||
config,
|
||||
&["--print=all-target-specs-json", "-Zunstable-options"],
|
||||
))
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
let mut current = None;
|
||||
let mut all_targets = HashSet::new();
|
||||
let mut all_archs = HashSet::new();
|
||||
let mut all_oses = HashSet::new();
|
||||
let mut all_oses_and_envs = HashSet::new();
|
||||
let mut all_envs = HashSet::new();
|
||||
let mut all_abis = HashSet::new();
|
||||
let mut all_families = HashSet::new();
|
||||
let mut all_pointer_widths = HashSet::new();
|
||||
|
||||
for (target, cfg) in targets.into_iter() {
|
||||
all_archs.insert(cfg.arch.clone());
|
||||
all_oses.insert(cfg.os.clone());
|
||||
all_oses_and_envs.insert(cfg.os_and_env());
|
||||
all_envs.insert(cfg.env.clone());
|
||||
all_abis.insert(cfg.abi.clone());
|
||||
for family in &cfg.families {
|
||||
all_families.insert(family.clone());
|
||||
}
|
||||
all_pointer_widths.insert(format!("{}bit", cfg.pointer_width));
|
||||
|
||||
if target == config.target {
|
||||
current = Some(cfg);
|
||||
}
|
||||
all_targets.insert(target.into());
|
||||
}
|
||||
|
||||
Self {
|
||||
current: current.expect("current target not found"),
|
||||
all_targets,
|
||||
all_archs,
|
||||
all_oses,
|
||||
all_oses_and_envs,
|
||||
all_envs,
|
||||
all_abis,
|
||||
all_families,
|
||||
all_pointer_widths,
|
||||
}
|
||||
}
|
||||
|
||||
// #[cfg(bootstrap)]
|
||||
// Needed only for one cycle, remove during the bootstrap bump.
|
||||
fn collect_all_slow(config: &Config) -> HashMap<String, TargetCfg> {
|
||||
let mut result = HashMap::new();
|
||||
for target in rustc_output(config, &["--print=target-list"]).trim().lines() {
|
||||
let json = rustc_output(
|
||||
config,
|
||||
&["--print=target-spec-json", "-Zunstable-options", "--target", target],
|
||||
);
|
||||
match serde_json::from_str(&json) {
|
||||
Ok(res) => {
|
||||
result.insert(target.into(), res);
|
||||
}
|
||||
Err(err) => panic!("failed to parse target spec for {target}: {err}"),
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct TargetCfg {
|
||||
arch: String,
|
||||
os: String,
|
||||
env: String,
|
||||
abi: String,
|
||||
families: Vec<String>,
|
||||
pointer_width: u32,
|
||||
pub(crate) arch: String,
|
||||
#[serde(default = "default_os")]
|
||||
pub(crate) os: String,
|
||||
#[serde(default)]
|
||||
pub(crate) env: String,
|
||||
#[serde(default)]
|
||||
pub(crate) abi: String,
|
||||
#[serde(rename = "target-family", default)]
|
||||
pub(crate) families: Vec<String>,
|
||||
#[serde(rename = "target-pointer-width", deserialize_with = "serde_parse_u32")]
|
||||
pub(crate) pointer_width: u32,
|
||||
#[serde(rename = "target-endian", default)]
|
||||
endian: Endian,
|
||||
#[serde(rename = "panic-strategy", default)]
|
||||
panic: PanicStrategy,
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Clone, Debug)]
|
||||
impl TargetCfg {
|
||||
pub(crate) fn os_and_env(&self) -> String {
|
||||
format!("{}-{}", self.os, self.env)
|
||||
}
|
||||
}
|
||||
|
||||
fn default_os() -> String {
|
||||
"none".into()
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Clone, Debug, Default, serde::Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum Endian {
|
||||
#[default]
|
||||
Little,
|
||||
Big,
|
||||
}
|
||||
|
||||
impl TargetCfg {
|
||||
fn new(config: &Config) -> TargetCfg {
|
||||
let mut command = Command::new(&config.rustc_path);
|
||||
add_dylib_path(&mut command, iter::once(&config.compile_lib_path));
|
||||
let output = match command
|
||||
.arg("--print=cfg")
|
||||
.arg("--target")
|
||||
.arg(&config.target)
|
||||
.args(&config.target_rustcflags)
|
||||
.output()
|
||||
{
|
||||
Ok(output) => output,
|
||||
Err(e) => panic!("error: failed to get cfg info from {:?}: {e}", config.rustc_path),
|
||||
};
|
||||
if !output.status.success() {
|
||||
panic!(
|
||||
"error: failed to get cfg info from {:?}\n--- stdout\n{}\n--- stderr\n{}",
|
||||
config.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 families = Vec::new();
|
||||
let mut pointer_width = None;
|
||||
let mut endian = None;
|
||||
let mut panic = 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_family" => families.push(value.to_string()),
|
||||
"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}"),
|
||||
})
|
||||
}
|
||||
"panic" => {
|
||||
panic = match value {
|
||||
"abort" => Some(PanicStrategy::Abort),
|
||||
"unwind" => Some(PanicStrategy::Unwind),
|
||||
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(),
|
||||
families,
|
||||
pointer_width: pointer_width.unwrap(),
|
||||
endian: endian.unwrap(),
|
||||
panic: panic.unwrap(),
|
||||
}
|
||||
fn rustc_output(config: &Config, args: &[&str]) -> String {
|
||||
let mut command = Command::new(&config.rustc_path);
|
||||
add_dylib_path(&mut command, iter::once(&config.compile_lib_path));
|
||||
command.args(&config.target_rustcflags).args(args);
|
||||
command.env("RUSTC_BOOTSTRAP", "1");
|
||||
|
||||
let output = match command.output() {
|
||||
Ok(output) => output,
|
||||
Err(e) => panic!("error: failed to run {command:?}: {e}"),
|
||||
};
|
||||
if !output.status.success() {
|
||||
panic!(
|
||||
"error: failed to run {command:?}\n--- stdout\n{}\n--- stderr\n{}",
|
||||
String::from_utf8(output.stdout).unwrap(),
|
||||
String::from_utf8(output.stderr).unwrap(),
|
||||
);
|
||||
}
|
||||
String::from_utf8(output.stdout).unwrap()
|
||||
}
|
||||
|
||||
fn serde_parse_u32<'de, D: Deserializer<'de>>(deserializer: D) -> Result<u32, D::Error> {
|
||||
let string = String::deserialize(deserializer)?;
|
||||
string.parse().map_err(D::Error::custom)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -8,22 +8,16 @@ use std::process::Command;
|
||||
|
||||
use tracing::*;
|
||||
|
||||
use crate::common::{CompareMode, Config, Debugger, FailMode, Mode, PassMode};
|
||||
use crate::common::{Config, Debugger, FailMode, Mode, PassMode};
|
||||
use crate::header::cfg::parse_cfg_name_directive;
|
||||
use crate::header::cfg::MatchOutcome;
|
||||
use crate::util;
|
||||
use crate::{extract_cdb_version, extract_gdb_version};
|
||||
|
||||
mod cfg;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
/// The result of parse_cfg_name_directive.
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
enum ParsedNameDirective {
|
||||
/// No match.
|
||||
NoMatch,
|
||||
/// Match.
|
||||
Match,
|
||||
}
|
||||
|
||||
/// Properties which must be known very early, before actually running
|
||||
/// the test.
|
||||
#[derive(Default)]
|
||||
@ -647,7 +641,7 @@ impl Config {
|
||||
}
|
||||
|
||||
fn parse_custom_normalization(&self, mut line: &str, prefix: &str) -> Option<(String, String)> {
|
||||
if self.parse_cfg_name_directive(line, prefix) == ParsedNameDirective::Match {
|
||||
if parse_cfg_name_directive(self, line, prefix).outcome == MatchOutcome::Match {
|
||||
let from = parse_normalization_string(&mut line)?;
|
||||
let to = parse_normalization_string(&mut line)?;
|
||||
Some((from, to))
|
||||
@ -664,68 +658,6 @@ impl Config {
|
||||
self.parse_name_directive(line, "needs-profiler-support")
|
||||
}
|
||||
|
||||
/// Parses a name-value directive which contains config-specific information, e.g., `ignore-x86`
|
||||
/// or `normalize-stderr-32bit`.
|
||||
fn parse_cfg_name_directive(&self, line: &str, prefix: &str) -> ParsedNameDirective {
|
||||
if !line.as_bytes().starts_with(prefix.as_bytes()) {
|
||||
return ParsedNameDirective::NoMatch;
|
||||
}
|
||||
if line.as_bytes().get(prefix.len()) != Some(&b'-') {
|
||||
return ParsedNameDirective::NoMatch;
|
||||
}
|
||||
|
||||
let name = line[prefix.len() + 1..].split(&[':', ' '][..]).next().unwrap();
|
||||
|
||||
let matches_pointer_width = || {
|
||||
name.strip_suffix("bit")
|
||||
.and_then(|width| width.parse::<u32>().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
|
||||
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() ||
|
||||
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" && self.is_big_endian()) ||
|
||||
(self.remote_test_client.is_some() && name == "remote") ||
|
||||
match self.compare_mode {
|
||||
Some(CompareMode::Polonius) => name == "compare-mode-polonius",
|
||||
Some(CompareMode::Chalk) => name == "compare-mode-chalk",
|
||||
Some(CompareMode::NextSolver) => name == "compare-mode-next-solver",
|
||||
Some(CompareMode::SplitDwarf) => name == "compare-mode-split-dwarf",
|
||||
Some(CompareMode::SplitDwarfSingle) => name == "compare-mode-split-dwarf-single",
|
||||
None => false,
|
||||
} ||
|
||||
(cfg!(debug_assertions) && name == "debug") ||
|
||||
match self.debugger {
|
||||
Some(Debugger::Cdb) => name == "cdb",
|
||||
Some(Debugger::Gdb) => name == "gdb",
|
||||
Some(Debugger::Lldb) => name == "lldb",
|
||||
None => false,
|
||||
};
|
||||
|
||||
if is_match { ParsedNameDirective::Match } else { ParsedNameDirective::NoMatch }
|
||||
}
|
||||
|
||||
fn has_cfg_prefix(&self, line: &str, prefix: &str) -> bool {
|
||||
// returns whether this line contains this prefix or not. For prefix
|
||||
// "ignore", returns true if line says "ignore-x86_64", "ignore-arch",
|
||||
@ -992,21 +924,44 @@ pub fn make_test_description<R: Read>(
|
||||
}
|
||||
};
|
||||
}
|
||||
ignore = match config.parse_cfg_name_directive(ln, "ignore") {
|
||||
ParsedNameDirective::Match => {
|
||||
ignore_message = Some("cfg -> ignore => Match");
|
||||
true
|
||||
}
|
||||
ParsedNameDirective::NoMatch => ignore,
|
||||
};
|
||||
|
||||
if config.has_cfg_prefix(ln, "only") {
|
||||
ignore = match config.parse_cfg_name_directive(ln, "only") {
|
||||
ParsedNameDirective::Match => ignore,
|
||||
ParsedNameDirective::NoMatch => {
|
||||
ignore_message = Some("cfg -> only => NoMatch");
|
||||
{
|
||||
let parsed = parse_cfg_name_directive(config, ln, "ignore");
|
||||
ignore = match parsed.outcome {
|
||||
MatchOutcome::Match => {
|
||||
let reason = parsed.pretty_reason.unwrap();
|
||||
// The ignore reason must be a &'static str, so we have to leak memory to
|
||||
// create it. This is fine, as the header is parsed only at the start of
|
||||
// compiletest so it won't grow indefinitely.
|
||||
ignore_message = Some(Box::leak(Box::<str>::from(match parsed.comment {
|
||||
Some(comment) => format!("ignored {reason} ({comment})"),
|
||||
None => format!("ignored {reason}"),
|
||||
})) as &str);
|
||||
true
|
||||
}
|
||||
MatchOutcome::NoMatch => ignore,
|
||||
MatchOutcome::External => ignore,
|
||||
MatchOutcome::Invalid => panic!("invalid line in {}: {ln}", path.display()),
|
||||
};
|
||||
}
|
||||
|
||||
if config.has_cfg_prefix(ln, "only") {
|
||||
let parsed = parse_cfg_name_directive(config, ln, "only");
|
||||
ignore = match parsed.outcome {
|
||||
MatchOutcome::Match => ignore,
|
||||
MatchOutcome::NoMatch => {
|
||||
let reason = parsed.pretty_reason.unwrap();
|
||||
// The ignore reason must be a &'static str, so we have to leak memory to
|
||||
// create it. This is fine, as the header is parsed only at the start of
|
||||
// compiletest so it won't grow indefinitely.
|
||||
ignore_message = Some(Box::leak(Box::<str>::from(match parsed.comment {
|
||||
Some(comment) => format!("only executed {reason} ({comment})"),
|
||||
None => format!("only executed {reason}"),
|
||||
})) as &str);
|
||||
true
|
||||
}
|
||||
MatchOutcome::External => ignore,
|
||||
MatchOutcome::Invalid => panic!("invalid line in {}: {ln}", path.display()),
|
||||
};
|
||||
}
|
||||
|
||||
|
320
src/tools/compiletest/src/header/cfg.rs
Normal file
320
src/tools/compiletest/src/header/cfg.rs
Normal file
@ -0,0 +1,320 @@
|
||||
use crate::common::{CompareMode, Config, Debugger};
|
||||
use std::collections::HashSet;
|
||||
|
||||
const EXTRA_ARCHS: &[&str] = &["spirv"];
|
||||
|
||||
/// Parses a name-value directive which contains config-specific information, e.g., `ignore-x86`
|
||||
/// or `normalize-stderr-32bit`.
|
||||
pub(super) fn parse_cfg_name_directive<'a>(
|
||||
config: &Config,
|
||||
line: &'a str,
|
||||
prefix: &str,
|
||||
) -> ParsedNameDirective<'a> {
|
||||
if !line.as_bytes().starts_with(prefix.as_bytes()) {
|
||||
return ParsedNameDirective::invalid();
|
||||
}
|
||||
if line.as_bytes().get(prefix.len()) != Some(&b'-') {
|
||||
return ParsedNameDirective::invalid();
|
||||
}
|
||||
let line = &line[prefix.len() + 1..];
|
||||
|
||||
let (name, comment) =
|
||||
line.split_once(&[':', ' ']).map(|(l, c)| (l, Some(c))).unwrap_or((line, None));
|
||||
|
||||
// Some of the matchers might be "" depending on what the target information is. To avoid
|
||||
// problems we outright reject empty directives.
|
||||
if name == "" {
|
||||
return ParsedNameDirective::invalid();
|
||||
}
|
||||
|
||||
let mut outcome = MatchOutcome::Invalid;
|
||||
let mut message = None;
|
||||
|
||||
macro_rules! condition {
|
||||
(
|
||||
name: $name:expr,
|
||||
$(allowed_names: $allowed_names:expr,)?
|
||||
$(condition: $condition:expr,)?
|
||||
message: $($message:tt)*
|
||||
) => {{
|
||||
// This is not inlined to avoid problems with macro repetitions.
|
||||
let format_message = || format!($($message)*);
|
||||
|
||||
if outcome != MatchOutcome::Invalid {
|
||||
// Ignore all other matches if we already found one
|
||||
} else if $name.custom_matches(name) {
|
||||
message = Some(format_message());
|
||||
if true $(&& $condition)? {
|
||||
outcome = MatchOutcome::Match;
|
||||
} else {
|
||||
outcome = MatchOutcome::NoMatch;
|
||||
}
|
||||
}
|
||||
$(else if $allowed_names.custom_contains(name) {
|
||||
message = Some(format_message());
|
||||
outcome = MatchOutcome::NoMatch;
|
||||
})?
|
||||
}};
|
||||
}
|
||||
|
||||
let target_cfgs = config.target_cfgs();
|
||||
let target_cfg = config.target_cfg();
|
||||
|
||||
condition! {
|
||||
name: "test",
|
||||
message: "always"
|
||||
}
|
||||
condition! {
|
||||
name: &config.target,
|
||||
allowed_names: &target_cfgs.all_targets,
|
||||
message: "when the target is {name}"
|
||||
}
|
||||
condition! {
|
||||
name: &[
|
||||
Some(&*target_cfg.os),
|
||||
// If something is ignored for emscripten, it likely also needs to be
|
||||
// ignored for wasm32-unknown-unknown.
|
||||
(config.target == "wasm32-unknown-unknown").then_some("emscripten"),
|
||||
],
|
||||
allowed_names: &target_cfgs.all_oses,
|
||||
message: "when the operative system is {name}"
|
||||
}
|
||||
condition! {
|
||||
name: &target_cfg.env,
|
||||
allowed_names: &target_cfgs.all_envs,
|
||||
message: "when the target environment is {name}"
|
||||
}
|
||||
condition! {
|
||||
name: &target_cfg.os_and_env(),
|
||||
allowed_names: &target_cfgs.all_oses_and_envs,
|
||||
message: "when the operative system and target environment are {name}"
|
||||
}
|
||||
condition! {
|
||||
name: &target_cfg.abi,
|
||||
allowed_names: &target_cfgs.all_abis,
|
||||
message: "when the ABI is {name}"
|
||||
}
|
||||
condition! {
|
||||
name: &target_cfg.arch,
|
||||
allowed_names: ContainsEither { a: &target_cfgs.all_archs, b: &EXTRA_ARCHS },
|
||||
message: "when the architecture is {name}"
|
||||
}
|
||||
condition! {
|
||||
name: format!("{}bit", target_cfg.pointer_width),
|
||||
allowed_names: &target_cfgs.all_pointer_widths,
|
||||
message: "when the pointer width is {name}"
|
||||
}
|
||||
condition! {
|
||||
name: &*target_cfg.families,
|
||||
allowed_names: &target_cfgs.all_families,
|
||||
message: "when the target family is {name}"
|
||||
}
|
||||
|
||||
// `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).
|
||||
condition! {
|
||||
name: "wasm32-bare",
|
||||
condition: config.target == "wasm32-unknown-unknown",
|
||||
message: "when the target is WASM"
|
||||
}
|
||||
|
||||
condition! {
|
||||
name: "asmjs",
|
||||
condition: config.target.starts_with("asmjs"),
|
||||
message: "when the architecture is asm.js",
|
||||
}
|
||||
condition! {
|
||||
name: "thumb",
|
||||
condition: config.target.starts_with("thumb"),
|
||||
message: "when the architecture is part of the Thumb family"
|
||||
}
|
||||
|
||||
condition! {
|
||||
name: &config.channel,
|
||||
allowed_names: &["stable", "beta", "nightly"],
|
||||
message: "when the release channel is {name}",
|
||||
}
|
||||
condition! {
|
||||
name: "cross-compile",
|
||||
condition: config.target != config.host,
|
||||
message: "when cross-compiling"
|
||||
}
|
||||
condition! {
|
||||
name: "endian-big",
|
||||
condition: config.is_big_endian(),
|
||||
message: "on big-endian targets",
|
||||
}
|
||||
condition! {
|
||||
name: config.stage_id.split('-').next().unwrap(),
|
||||
allowed_names: &["stage0", "stage1", "stage2"],
|
||||
message: "when the bootstrapping stage is {name}",
|
||||
}
|
||||
condition! {
|
||||
name: "remote",
|
||||
condition: config.remote_test_client.is_some(),
|
||||
message: "when running tests remotely",
|
||||
}
|
||||
condition! {
|
||||
name: "debug",
|
||||
condition: cfg!(debug_assertions),
|
||||
message: "when building with debug assertions",
|
||||
}
|
||||
condition! {
|
||||
name: config.debugger.as_ref().map(|d| d.to_str()),
|
||||
allowed_names: &Debugger::STR_VARIANTS,
|
||||
message: "when the debugger is {name}",
|
||||
}
|
||||
condition! {
|
||||
name: config.compare_mode
|
||||
.as_ref()
|
||||
.map(|d| format!("compare-mode-{}", d.to_str())),
|
||||
allowed_names: ContainsPrefixed {
|
||||
prefix: "compare-mode-",
|
||||
inner: CompareMode::STR_VARIANTS,
|
||||
},
|
||||
message: "when comparing with {name}",
|
||||
}
|
||||
|
||||
if prefix == "ignore" && outcome == MatchOutcome::Invalid {
|
||||
// Don't error out for ignore-tidy-* diretives, as those are not handled by compiletest.
|
||||
if name.starts_with("tidy-") {
|
||||
outcome = MatchOutcome::External;
|
||||
}
|
||||
|
||||
// Don't error out for ignore-pass, as that is handled elsewhere.
|
||||
if name == "pass" {
|
||||
outcome = MatchOutcome::External;
|
||||
}
|
||||
|
||||
// Don't error out for ignore-llvm-version, that has a custom syntax and is handled
|
||||
// elsewhere.
|
||||
if name == "llvm-version" {
|
||||
outcome = MatchOutcome::External;
|
||||
}
|
||||
|
||||
// Don't error out for ignore-llvm-version, that has a custom syntax and is handled
|
||||
// elsewhere.
|
||||
if name == "gdb-version" {
|
||||
outcome = MatchOutcome::External;
|
||||
}
|
||||
}
|
||||
|
||||
ParsedNameDirective {
|
||||
name: Some(name),
|
||||
comment: comment.map(|c| c.trim().trim_start_matches('-').trim()),
|
||||
outcome,
|
||||
pretty_reason: message,
|
||||
}
|
||||
}
|
||||
|
||||
/// The result of parse_cfg_name_directive.
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
pub(super) struct ParsedNameDirective<'a> {
|
||||
pub(super) name: Option<&'a str>,
|
||||
pub(super) pretty_reason: Option<String>,
|
||||
pub(super) comment: Option<&'a str>,
|
||||
pub(super) outcome: MatchOutcome,
|
||||
}
|
||||
|
||||
impl ParsedNameDirective<'_> {
|
||||
fn invalid() -> Self {
|
||||
Self { name: None, pretty_reason: None, comment: None, outcome: MatchOutcome::NoMatch }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
pub(super) enum MatchOutcome {
|
||||
/// No match.
|
||||
NoMatch,
|
||||
/// Match.
|
||||
Match,
|
||||
/// The directive was invalid.
|
||||
Invalid,
|
||||
/// The directive is handled by other parts of our tooling.
|
||||
External,
|
||||
}
|
||||
|
||||
trait CustomContains {
|
||||
fn custom_contains(&self, item: &str) -> bool;
|
||||
}
|
||||
|
||||
impl CustomContains for HashSet<String> {
|
||||
fn custom_contains(&self, item: &str) -> bool {
|
||||
self.contains(item)
|
||||
}
|
||||
}
|
||||
|
||||
impl CustomContains for &[&str] {
|
||||
fn custom_contains(&self, item: &str) -> bool {
|
||||
self.contains(&item)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> CustomContains for [&str; N] {
|
||||
fn custom_contains(&self, item: &str) -> bool {
|
||||
self.contains(&item)
|
||||
}
|
||||
}
|
||||
|
||||
struct ContainsPrefixed<T: CustomContains> {
|
||||
prefix: &'static str,
|
||||
inner: T,
|
||||
}
|
||||
|
||||
impl<T: CustomContains> CustomContains for ContainsPrefixed<T> {
|
||||
fn custom_contains(&self, item: &str) -> bool {
|
||||
match item.strip_prefix(self.prefix) {
|
||||
Some(stripped) => self.inner.custom_contains(stripped),
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ContainsEither<'a, A: CustomContains, B: CustomContains> {
|
||||
a: &'a A,
|
||||
b: &'a B,
|
||||
}
|
||||
|
||||
impl<A: CustomContains, B: CustomContains> CustomContains for ContainsEither<'_, A, B> {
|
||||
fn custom_contains(&self, item: &str) -> bool {
|
||||
self.a.custom_contains(item) || self.b.custom_contains(item)
|
||||
}
|
||||
}
|
||||
|
||||
trait CustomMatches {
|
||||
fn custom_matches(&self, name: &str) -> bool;
|
||||
}
|
||||
|
||||
impl CustomMatches for &str {
|
||||
fn custom_matches(&self, name: &str) -> bool {
|
||||
name == *self
|
||||
}
|
||||
}
|
||||
|
||||
impl CustomMatches for String {
|
||||
fn custom_matches(&self, name: &str) -> bool {
|
||||
name == self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: CustomMatches> CustomMatches for &[T] {
|
||||
fn custom_matches(&self, name: &str) -> bool {
|
||||
self.iter().any(|m| m.custom_matches(name))
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize, T: CustomMatches> CustomMatches for [T; N] {
|
||||
fn custom_matches(&self, name: &str) -> bool {
|
||||
self.iter().any(|m| m.custom_matches(name))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: CustomMatches> CustomMatches for Option<T> {
|
||||
fn custom_matches(&self, name: &str) -> bool {
|
||||
match self {
|
||||
Some(inner) => inner.custom_matches(name),
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
}
|
@ -47,7 +47,7 @@ fn config() -> Config {
|
||||
"--src-base=",
|
||||
"--build-base=",
|
||||
"--sysroot-base=",
|
||||
"--stage-id=stage2",
|
||||
"--stage-id=stage2-x86_64-unknown-linux-gnu",
|
||||
"--cc=c",
|
||||
"--cxx=c++",
|
||||
"--cflags=",
|
||||
@ -174,7 +174,7 @@ fn ignore_target() {
|
||||
assert!(check_ignore(&config, "// ignore-gnu"));
|
||||
assert!(check_ignore(&config, "// ignore-64bit"));
|
||||
|
||||
assert!(!check_ignore(&config, "// ignore-i686"));
|
||||
assert!(!check_ignore(&config, "// ignore-x86"));
|
||||
assert!(!check_ignore(&config, "// ignore-windows"));
|
||||
assert!(!check_ignore(&config, "// ignore-msvc"));
|
||||
assert!(!check_ignore(&config, "// ignore-32bit"));
|
||||
@ -200,7 +200,7 @@ fn only_target() {
|
||||
#[test]
|
||||
fn stage() {
|
||||
let mut config = config();
|
||||
config.stage_id = "stage1".to_owned();
|
||||
config.stage_id = "stage1-x86_64-unknown-linux-gnu".to_owned();
|
||||
|
||||
assert!(check_ignore(&config, "// ignore-stage1"));
|
||||
assert!(!check_ignore(&config, "// ignore-stage2"));
|
||||
|
@ -6,12 +6,12 @@
|
||||
extern crate test;
|
||||
|
||||
use crate::common::{expected_output_path, output_base_dir, output_relative_path, UI_EXTENSIONS};
|
||||
use crate::common::{CompareMode, Config, Debugger, Mode, PassMode, TestPaths};
|
||||
use crate::common::{Config, Debugger, Mode, PassMode, TestPaths};
|
||||
use crate::util::logv;
|
||||
use build_helper::git::{get_git_modified_files, get_git_untracked_files};
|
||||
use core::panic;
|
||||
use getopts::Options;
|
||||
use lazycell::LazyCell;
|
||||
use lazycell::AtomicLazyCell;
|
||||
use std::collections::BTreeSet;
|
||||
use std::ffi::OsString;
|
||||
use std::fs;
|
||||
@ -25,6 +25,7 @@ use tracing::*;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
use self::header::{make_test_description, EarlyProps};
|
||||
use std::sync::Arc;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
@ -42,7 +43,7 @@ pub mod util;
|
||||
fn main() {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
let config = parse_config(env::args().collect());
|
||||
let config = Arc::new(parse_config(env::args().collect()));
|
||||
|
||||
if config.valgrind_path.is_none() && config.force_valgrind {
|
||||
panic!("Can't find Valgrind to run Valgrind tests");
|
||||
@ -293,7 +294,9 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
||||
only_modified: matches.opt_present("only-modified"),
|
||||
color,
|
||||
remote_test_client: matches.opt_str("remote-test-client").map(PathBuf::from),
|
||||
compare_mode: matches.opt_str("compare-mode").map(CompareMode::parse),
|
||||
compare_mode: matches
|
||||
.opt_str("compare-mode")
|
||||
.map(|s| s.parse().expect("invalid --compare-mode provided")),
|
||||
rustfix_coverage: matches.opt_present("rustfix-coverage"),
|
||||
has_tidy,
|
||||
channel: matches.opt_str("channel").unwrap(),
|
||||
@ -311,7 +314,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
||||
|
||||
force_rerun: matches.opt_present("force-rerun"),
|
||||
|
||||
target_cfg: LazyCell::new(),
|
||||
target_cfgs: AtomicLazyCell::new(),
|
||||
|
||||
nocapture: matches.opt_present("nocapture"),
|
||||
}
|
||||
@ -367,7 +370,7 @@ pub fn opt_str2(maybestr: Option<String>) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_tests(config: Config) {
|
||||
pub fn run_tests(config: Arc<Config>) {
|
||||
// If we want to collect rustfix coverage information,
|
||||
// we first make sure that the coverage file does not exist.
|
||||
// It will be created later on.
|
||||
@ -409,7 +412,7 @@ pub fn run_tests(config: Config) {
|
||||
};
|
||||
|
||||
let mut tests = Vec::new();
|
||||
for c in &configs {
|
||||
for c in configs {
|
||||
let mut found_paths = BTreeSet::new();
|
||||
make_tests(c, &mut tests, &mut found_paths);
|
||||
check_overlapping_tests(&found_paths);
|
||||
@ -431,7 +434,11 @@ pub fn run_tests(config: Config) {
|
||||
println!(
|
||||
"Some tests failed in compiletest suite={}{} mode={} host={} target={}",
|
||||
config.suite,
|
||||
config.compare_mode.map(|c| format!(" compare_mode={:?}", c)).unwrap_or_default(),
|
||||
config
|
||||
.compare_mode
|
||||
.as_ref()
|
||||
.map(|c| format!(" compare_mode={:?}", c))
|
||||
.unwrap_or_default(),
|
||||
config.mode,
|
||||
config.host,
|
||||
config.target
|
||||
@ -451,13 +458,13 @@ pub fn run_tests(config: Config) {
|
||||
}
|
||||
}
|
||||
|
||||
fn configure_cdb(config: &Config) -> Option<Config> {
|
||||
fn configure_cdb(config: &Config) -> Option<Arc<Config>> {
|
||||
config.cdb.as_ref()?;
|
||||
|
||||
Some(Config { debugger: Some(Debugger::Cdb), ..config.clone() })
|
||||
Some(Arc::new(Config { debugger: Some(Debugger::Cdb), ..config.clone() }))
|
||||
}
|
||||
|
||||
fn configure_gdb(config: &Config) -> Option<Config> {
|
||||
fn configure_gdb(config: &Config) -> Option<Arc<Config>> {
|
||||
config.gdb_version?;
|
||||
|
||||
if config.matches_env("msvc") {
|
||||
@ -488,10 +495,10 @@ fn configure_gdb(config: &Config) -> Option<Config> {
|
||||
env::set_var("RUST_TEST_THREADS", "1");
|
||||
}
|
||||
|
||||
Some(Config { debugger: Some(Debugger::Gdb), ..config.clone() })
|
||||
Some(Arc::new(Config { debugger: Some(Debugger::Gdb), ..config.clone() }))
|
||||
}
|
||||
|
||||
fn configure_lldb(config: &Config) -> Option<Config> {
|
||||
fn configure_lldb(config: &Config) -> Option<Arc<Config>> {
|
||||
config.lldb_python_dir.as_ref()?;
|
||||
|
||||
if let Some(350) = config.lldb_version {
|
||||
@ -504,7 +511,7 @@ fn configure_lldb(config: &Config) -> Option<Config> {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(Config { debugger: Some(Debugger::Lldb), ..config.clone() })
|
||||
Some(Arc::new(Config { debugger: Some(Debugger::Lldb), ..config.clone() }))
|
||||
}
|
||||
|
||||
pub fn test_opts(config: &Config) -> test::TestOpts {
|
||||
@ -539,17 +546,17 @@ pub fn test_opts(config: &Config) -> test::TestOpts {
|
||||
}
|
||||
|
||||
pub fn make_tests(
|
||||
config: &Config,
|
||||
config: Arc<Config>,
|
||||
tests: &mut Vec<test::TestDescAndFn>,
|
||||
found_paths: &mut BTreeSet<PathBuf>,
|
||||
) {
|
||||
debug!("making tests from {:?}", config.src_base.display());
|
||||
let inputs = common_inputs_stamp(config);
|
||||
let modified_tests = modified_tests(config, &config.src_base).unwrap_or_else(|err| {
|
||||
let inputs = common_inputs_stamp(&config);
|
||||
let modified_tests = modified_tests(&config, &config.src_base).unwrap_or_else(|err| {
|
||||
panic!("modified_tests got error from dir: {}, error: {}", config.src_base.display(), err)
|
||||
});
|
||||
collect_tests_from_dir(
|
||||
config,
|
||||
config.clone(),
|
||||
&config.src_base,
|
||||
&PathBuf::new(),
|
||||
&inputs,
|
||||
@ -620,7 +627,7 @@ fn modified_tests(config: &Config, dir: &Path) -> Result<Vec<PathBuf>, String> {
|
||||
}
|
||||
|
||||
fn collect_tests_from_dir(
|
||||
config: &Config,
|
||||
config: Arc<Config>,
|
||||
dir: &Path,
|
||||
relative_dir_path: &Path,
|
||||
inputs: &Stamp,
|
||||
@ -648,7 +655,7 @@ fn collect_tests_from_dir(
|
||||
// sequential loop because otherwise, if we do it in the
|
||||
// tests themselves, they race for the privilege of
|
||||
// creating the directories and sometimes fail randomly.
|
||||
let build_dir = output_relative_path(config, relative_dir_path);
|
||||
let build_dir = output_relative_path(&config, relative_dir_path);
|
||||
fs::create_dir_all(&build_dir).unwrap();
|
||||
|
||||
// Add each `.rs` file as a test, and recurse further on any
|
||||
@ -664,13 +671,13 @@ fn collect_tests_from_dir(
|
||||
let paths =
|
||||
TestPaths { file: file_path, relative_dir: relative_dir_path.to_path_buf() };
|
||||
|
||||
tests.extend(make_test(config, &paths, inputs))
|
||||
tests.extend(make_test(config.clone(), &paths, inputs))
|
||||
} else if file_path.is_dir() {
|
||||
let relative_file_path = relative_dir_path.join(file.file_name());
|
||||
if &file_name != "auxiliary" {
|
||||
debug!("found directory: {:?}", file_path.display());
|
||||
collect_tests_from_dir(
|
||||
config,
|
||||
config.clone(),
|
||||
&file_path,
|
||||
&relative_file_path,
|
||||
inputs,
|
||||
@ -699,14 +706,18 @@ pub fn is_test(file_name: &OsString) -> bool {
|
||||
!invalid_prefixes.iter().any(|p| file_name.starts_with(p))
|
||||
}
|
||||
|
||||
fn make_test(config: &Config, testpaths: &TestPaths, inputs: &Stamp) -> Vec<test::TestDescAndFn> {
|
||||
fn make_test(
|
||||
config: Arc<Config>,
|
||||
testpaths: &TestPaths,
|
||||
inputs: &Stamp,
|
||||
) -> Vec<test::TestDescAndFn> {
|
||||
let test_path = if config.mode == Mode::RunMake {
|
||||
// Parse directives in the Makefile
|
||||
testpaths.file.join("Makefile")
|
||||
} else {
|
||||
PathBuf::from(&testpaths.file)
|
||||
};
|
||||
let early_props = EarlyProps::from_file(config, &test_path);
|
||||
let early_props = EarlyProps::from_file(&config, &test_path);
|
||||
|
||||
// Incremental tests are special, they inherently cannot be run in parallel.
|
||||
// `runtest::run` will be responsible for iterating over revisions.
|
||||
@ -721,19 +732,22 @@ fn make_test(config: &Config, testpaths: &TestPaths, inputs: &Stamp) -> Vec<test
|
||||
let src_file =
|
||||
std::fs::File::open(&test_path).expect("open test file to parse ignores");
|
||||
let cfg = revision.map(|v| &**v);
|
||||
let test_name = crate::make_test_name(config, testpaths, revision);
|
||||
let mut desc = make_test_description(config, test_name, &test_path, src_file, cfg);
|
||||
let test_name = crate::make_test_name(&config, testpaths, revision);
|
||||
let mut desc = make_test_description(&config, test_name, &test_path, src_file, cfg);
|
||||
// Ignore tests that already run and are up to date with respect to inputs.
|
||||
if !config.force_rerun {
|
||||
desc.ignore |= is_up_to_date(
|
||||
config,
|
||||
&config,
|
||||
testpaths,
|
||||
&early_props,
|
||||
revision.map(|s| s.as_str()),
|
||||
inputs,
|
||||
);
|
||||
}
|
||||
test::TestDescAndFn { desc, testfn: make_test_closure(config, testpaths, revision) }
|
||||
test::TestDescAndFn {
|
||||
desc,
|
||||
testfn: make_test_closure(config.clone(), testpaths, revision),
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
@ -867,7 +881,7 @@ fn make_test_name(
|
||||
}
|
||||
|
||||
fn make_test_closure(
|
||||
config: &Config,
|
||||
config: Arc<Config>,
|
||||
testpaths: &TestPaths,
|
||||
revision: Option<&String>,
|
||||
) -> test::TestFn {
|
||||
|
@ -30,6 +30,7 @@ use std::iter;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Child, Command, ExitStatus, Output, Stdio};
|
||||
use std::str;
|
||||
use std::sync::Arc;
|
||||
|
||||
use glob::glob;
|
||||
use once_cell::sync::Lazy;
|
||||
@ -96,7 +97,7 @@ pub fn get_lib_name(lib: &str, dylib: bool) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(config: Config, testpaths: &TestPaths, revision: Option<&str>) {
|
||||
pub fn run(config: Arc<Config>, testpaths: &TestPaths, revision: Option<&str>) {
|
||||
match &*config.target {
|
||||
"arm-linux-androideabi"
|
||||
| "armv7-linux-androideabi"
|
||||
|
@ -17,7 +17,6 @@
|
||||
// ignore-wasm32
|
||||
// ignore-x86
|
||||
// ignore-x86_64
|
||||
// ignore-xcore
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
@ -1,39 +1,20 @@
|
||||
// ignore-aarch64
|
||||
// ignore-aarch64_be
|
||||
// ignore-arm
|
||||
// ignore-armeb
|
||||
// ignore-avr
|
||||
// ignore-bpfel
|
||||
// ignore-bpfeb
|
||||
// ignore-bpf
|
||||
// ignore-bpf
|
||||
// ignore-hexagon
|
||||
// ignore-mips
|
||||
// ignore-mips64
|
||||
// ignore-msp430
|
||||
// ignore-powerpc64
|
||||
// ignore-powerpc64le
|
||||
// ignore-powerpc
|
||||
// ignore-r600
|
||||
// ignore-amdgcn
|
||||
// ignore-sparc
|
||||
// ignore-sparcv9
|
||||
// ignore-sparcel
|
||||
// ignore-sparc64
|
||||
// ignore-s390x
|
||||
// ignore-tce
|
||||
// ignore-thumb
|
||||
// ignore-thumbeb
|
||||
// ignore-xcore
|
||||
// ignore-nvptx
|
||||
// ignore-nvptx64
|
||||
// ignore-le32
|
||||
// ignore-le64
|
||||
// ignore-amdil
|
||||
// ignore-amdil64
|
||||
// ignore-hsail
|
||||
// ignore-hsail64
|
||||
// ignore-spir
|
||||
// ignore-spir64
|
||||
// ignore-kalimba
|
||||
// ignore-shave
|
||||
// ignore-spirv
|
||||
// ignore-wasm32
|
||||
// ignore-wasm64
|
||||
// ignore-emscripten
|
||||
|
@ -1,39 +1,20 @@
|
||||
// ignore-aarch64
|
||||
// ignore-aarch64_be
|
||||
// ignore-arm
|
||||
// ignore-armeb
|
||||
// ignore-avr
|
||||
// ignore-bpfel
|
||||
// ignore-bpfeb
|
||||
// ignore-bpf
|
||||
// ignore-bpf
|
||||
// ignore-hexagon
|
||||
// ignore-mips
|
||||
// ignore-mips64
|
||||
// ignore-msp430
|
||||
// ignore-powerpc64
|
||||
// ignore-powerpc64le
|
||||
// ignore-powerpc
|
||||
// ignore-r600
|
||||
// ignore-amdgcn
|
||||
// ignore-sparc
|
||||
// ignore-sparcv9
|
||||
// ignore-sparcel
|
||||
// ignore-sparc64
|
||||
// ignore-s390x
|
||||
// ignore-tce
|
||||
// ignore-thumb
|
||||
// ignore-thumbeb
|
||||
// ignore-xcore
|
||||
// ignore-nvptx
|
||||
// ignore-nvptx64
|
||||
// ignore-le32
|
||||
// ignore-le64
|
||||
// ignore-amdil
|
||||
// ignore-amdil64
|
||||
// ignore-hsail
|
||||
// ignore-hsail64
|
||||
// ignore-spir
|
||||
// ignore-spir64
|
||||
// ignore-kalimba
|
||||
// ignore-shave
|
||||
// ignore-spirv
|
||||
// ignore-wasm32
|
||||
// ignore-wasm64
|
||||
// ignore-emscripten
|
||||
|
@ -1,39 +1,20 @@
|
||||
// ignore-aarch64
|
||||
// ignore-aarch64_be
|
||||
// ignore-arm
|
||||
// ignore-armeb
|
||||
// ignore-avr
|
||||
// ignore-bpfel
|
||||
// ignore-bpfeb
|
||||
// ignore-bpf
|
||||
// ignore-bpf
|
||||
// ignore-hexagon
|
||||
// ignore-mips
|
||||
// ignore-mips64
|
||||
// ignore-msp430
|
||||
// ignore-powerpc64
|
||||
// ignore-powerpc64le
|
||||
// ignore-powerpc
|
||||
// ignore-r600
|
||||
// ignore-amdgcn
|
||||
// ignore-sparc
|
||||
// ignore-sparcv9
|
||||
// ignore-sparcel
|
||||
// ignore-sparc64
|
||||
// ignore-s390x
|
||||
// ignore-tce
|
||||
// ignore-thumb
|
||||
// ignore-thumbeb
|
||||
// ignore-xcore
|
||||
// ignore-nvptx
|
||||
// ignore-nvptx64
|
||||
// ignore-le32
|
||||
// ignore-le64
|
||||
// ignore-amdil
|
||||
// ignore-amdil64
|
||||
// ignore-hsail
|
||||
// ignore-hsail64
|
||||
// ignore-spir
|
||||
// ignore-spir64
|
||||
// ignore-kalimba
|
||||
// ignore-shave
|
||||
// ignore-spirv
|
||||
// ignore-wasm32
|
||||
// ignore-wasm64
|
||||
// ignore-emscripten
|
||||
|
@ -1,9 +1,5 @@
|
||||
// compile-flags: -O -Zmerge-functions=disabled
|
||||
// ignore-x86
|
||||
// ignore-arm
|
||||
// ignore-emscripten
|
||||
// ignore-gnux32
|
||||
// ignore 32-bit platforms (LLVM has a bug with them)
|
||||
// ignore-32bit LLVM has a bug with them
|
||||
// ignore-debug
|
||||
|
||||
// Check that LLVM understands that `Iter` pointer is not null. Issue #37945.
|
||||
|
@ -6,7 +6,6 @@
|
||||
// ignore-mips64
|
||||
// ignore-powerpc
|
||||
// ignore-powerpc64
|
||||
// ignore-powerpc64le
|
||||
// ignore-riscv64 see codegen/riscv-abi
|
||||
// ignore-s390x
|
||||
// ignore-sparc
|
||||
|
@ -2,7 +2,7 @@ include ../tools.mk
|
||||
|
||||
# only-x86_64
|
||||
# only-linux
|
||||
# ignore-gnux32
|
||||
# ignore-32bit
|
||||
|
||||
# How to manually run this
|
||||
# $ ./x.py test --target x86_64-unknown-linux-[musl,gnu] tests/run-make/static-pie
|
||||
|
@ -2,7 +2,7 @@ include ../tools.mk
|
||||
|
||||
# ignore-freebsd
|
||||
# ignore-openbsd
|
||||
# ignore-sunos
|
||||
# ignore-solaris
|
||||
|
||||
HOST := $(shell $(RUSTC) -vV | grep 'host:' | sed 's/host: //')
|
||||
ifeq ($(findstring i686,$(HOST)),i686)
|
||||
|
@ -1,2 +1,2 @@
|
||||
error: unknown print request `uwu`. Valid print requests are: `crate-name`, `file-names`, `sysroot`, `target-libdir`, `cfg`, `calling-conventions`, `target-list`, `target-cpus`, `target-features`, `relocation-models`, `code-models`, `tls-models`, `native-static-libs`, `stack-protector-strategies`, `target-spec-json`, `link-args`, `split-debuginfo`
|
||||
error: unknown print request `uwu`. Valid print requests are: `crate-name`, `file-names`, `sysroot`, `target-libdir`, `cfg`, `calling-conventions`, `target-list`, `target-cpus`, `target-features`, `relocation-models`, `code-models`, `tls-models`, `native-static-libs`, `stack-protector-strategies`, `target-spec-json`, `all-target-specs-json`, `link-args`, `split-debuginfo`
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// run-pass
|
||||
// Test that users are able to use stable mir APIs to retrieve information of the current crate
|
||||
|
||||
// ignore-stage-1
|
||||
// ignore-stage1
|
||||
// ignore-cross-compile
|
||||
// ignore-remote
|
||||
// edition: 2021
|
||||
|
@ -9,7 +9,6 @@
|
||||
// ignore-emscripten no processes
|
||||
// ignore-sgx no processes
|
||||
// ignore-musl FIXME #31506
|
||||
// ignore-pretty
|
||||
// ignore-fuchsia no exception handler registered for segfault
|
||||
// compile-flags: -C lto
|
||||
// no-prefer-dynamic
|
||||
|
@ -1,7 +1,7 @@
|
||||
// This checks that the attribute validation ICE in issue #105594 doesn't
|
||||
// recur.
|
||||
//
|
||||
// ignore-thumbv8m.base
|
||||
// ignore-thumbv8m.base-none-eabi
|
||||
#![feature(cmse_nonsecure_entry)]
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,6 +1,5 @@
|
||||
// run-pass
|
||||
#![allow(unused_unsafe)]
|
||||
// ignore-pretty issue #37199
|
||||
#![allow(while_true)]
|
||||
|
||||
fn main() {
|
||||
|
@ -1,6 +1,5 @@
|
||||
// run-pass
|
||||
#![allow(dead_code)]
|
||||
// ignore-pretty issue #37199
|
||||
|
||||
fn match_ref(v: Option<isize>) -> isize {
|
||||
match v {
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
#![allow(stable_features)]
|
||||
// ignore-windows - this is a unix-specific test
|
||||
// ignore-pretty issue #37199
|
||||
// ignore-emscripten no processes
|
||||
// ignore-sgx no processes
|
||||
// ignore-fuchsia no execvp syscall provided
|
||||
|
@ -1,5 +1,3 @@
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#![feature(decl_macro)]
|
||||
|
||||
macro m($t:ty, $e:expr) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0412]: cannot find type `S` in this scope
|
||||
--> $DIR/arguments.rs:16:8
|
||||
--> $DIR/arguments.rs:14:8
|
||||
|
|
||||
LL | m!(S, S);
|
||||
| ^ not found in this scope
|
||||
|
@ -1,5 +1,3 @@
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#![feature(decl_macro)]
|
||||
#![allow(unused)]
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0407]: method `method` is not a member of trait `Tr`
|
||||
--> $DIR/assoc_item_ctxt.rs:35:13
|
||||
--> $DIR/assoc_item_ctxt.rs:33:13
|
||||
|
|
||||
LL | fn method() {}
|
||||
| ^^^------^^^^^
|
||||
@ -13,7 +13,7 @@ LL | mac_trait_impl!();
|
||||
= note: this error originates in the macro `mac_trait_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0046]: not all trait items implemented, missing: `method`
|
||||
--> $DIR/assoc_item_ctxt.rs:34:9
|
||||
--> $DIR/assoc_item_ctxt.rs:32:9
|
||||
|
|
||||
LL | fn method();
|
||||
| ------------ `method` from trait
|
||||
|
@ -1,5 +1,4 @@
|
||||
// check-pass
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#![feature(decl_macro, associated_type_defaults)]
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! m {
|
||||
() => {
|
||||
|
@ -1,5 +1,3 @@
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#![feature(decl_macro)]
|
||||
|
||||
mod foo {
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: type `foo::S` is private
|
||||
--> $DIR/fields.rs:15:17
|
||||
--> $DIR/fields.rs:13:17
|
||||
|
|
||||
LL | let s = S { x: 0 };
|
||||
| ^^^^^^^^^^ private type
|
||||
@ -10,7 +10,7 @@ LL | let s = foo::m!(S, x);
|
||||
= note: this error originates in the macro `foo::m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: type `foo::S` is private
|
||||
--> $DIR/fields.rs:16:17
|
||||
--> $DIR/fields.rs:14:17
|
||||
|
|
||||
LL | let _ = s.x;
|
||||
| ^ private type
|
||||
@ -21,7 +21,7 @@ LL | let s = foo::m!(S, x);
|
||||
= note: this error originates in the macro `foo::m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: type `T` is private
|
||||
--> $DIR/fields.rs:18:17
|
||||
--> $DIR/fields.rs:16:17
|
||||
|
|
||||
LL | let t = T(0);
|
||||
| ^^^^ private type
|
||||
@ -32,7 +32,7 @@ LL | let s = foo::m!(S, x);
|
||||
= note: this error originates in the macro `foo::m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: type `T` is private
|
||||
--> $DIR/fields.rs:19:17
|
||||
--> $DIR/fields.rs:17:17
|
||||
|
|
||||
LL | let _ = t.0;
|
||||
| ^ private type
|
||||
|
@ -1,7 +1,6 @@
|
||||
// Ensure that generic parameters always have modern hygiene.
|
||||
|
||||
// check-pass
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#![feature(decl_macro, rustc_attrs)]
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#![feature(decl_macro)]
|
||||
|
||||
mod foo {
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: type `for<'a> fn(&'a foo::S) {foo::S::f}` is private
|
||||
--> $DIR/impl_items.rs:12:23
|
||||
--> $DIR/impl_items.rs:10:23
|
||||
|
|
||||
LL | let _: () = S.f();
|
||||
| ^ private type
|
||||
|
@ -1,5 +1,3 @@
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
// aux-build:intercrate.rs
|
||||
|
||||
#![feature(decl_macro)]
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: type `fn() -> u32 {foo::bar::f}` is private
|
||||
--> $DIR/intercrate.rs:10:16
|
||||
--> $DIR/intercrate.rs:8:16
|
||||
|
|
||||
LL | assert_eq!(intercrate::foo::m!(), 1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ private type
|
||||
|
@ -1,5 +1,4 @@
|
||||
// check-pass
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#![feature(decl_macro)]
|
||||
#![allow(unused)]
|
||||
|
@ -1,5 +1,4 @@
|
||||
// check-pass
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#![feature(decl_macro)]
|
||||
#![allow(unused)]
|
||||
|
@ -1,5 +1,4 @@
|
||||
// check-pass
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#![feature(decl_macro)]
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
// check-pass
|
||||
#![allow(dead_code)]
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
// aux-build:legacy_interaction.rs
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
// check-pass
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#![feature(decl_macro)]
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
// run-pass
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#![feature(decl_macro)]
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
// check-pass
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#![feature(decl_macro)]
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
// check-pass
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
// aux-build:my_crate.rs
|
||||
// aux-build:unhygienic_example.rs
|
||||
|
@ -1,5 +1,4 @@
|
||||
// run-pass
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
// aux-build:xcrate.rs
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
#![allow(unused_imports)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
// ignore-pretty issue #37195
|
||||
|
||||
#[path = "issue-26873-multifile/mod.rs"]
|
||||
mod multifile;
|
||||
|
@ -1,6 +1,5 @@
|
||||
// run-pass
|
||||
#![allow(dead_code)]
|
||||
// ignore-pretty issue #37199
|
||||
|
||||
// Don't panic on blocks without results
|
||||
// There are several tests in this run-pass that raised
|
||||
|
@ -1,5 +1,4 @@
|
||||
// run-pass
|
||||
// ignore-pretty issue #37199
|
||||
|
||||
pub struct Foo;
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
// run-pass
|
||||
// aux-build:issue-38190.rs
|
||||
// ignore-pretty issue #37195
|
||||
|
||||
#[macro_use]
|
||||
extern crate issue_38190;
|
||||
|
@ -2,7 +2,6 @@
|
||||
#![allow(dead_code)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
// ignore-pretty unreported
|
||||
|
||||
pub trait bomb { fn boom(&self, _: Ident); }
|
||||
pub struct S;
|
||||
|
@ -6,7 +6,6 @@
|
||||
// N.B., this file needs CRLF line endings. The .gitattributes file in
|
||||
// this directory should enforce it.
|
||||
|
||||
// ignore-pretty issue #37195
|
||||
|
||||
/// Doc comment that ends in CRLF
|
||||
pub fn foo() {}
|
||||
|
@ -1,5 +1,4 @@
|
||||
// run-pass
|
||||
// ignore-pretty issue #37195
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
// implementations for some macro_rules! macros as an implementation
|
||||
// detail.
|
||||
|
||||
// ignore-pretty issue #37195
|
||||
|
||||
// compile-flags: --test -C debug_assertions=yes
|
||||
// revisions: std core
|
||||
|
@ -1,7 +1,6 @@
|
||||
// run-pass
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
// ignore-pretty issue #37195
|
||||
|
||||
fn bar() {}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
// run-pass
|
||||
#![allow(stable_features)]
|
||||
|
||||
// ignore-pretty issue #37195
|
||||
|
||||
pub mod m1 {
|
||||
pub mod m2 {
|
||||
@ -14,9 +13,9 @@ pub mod m1 {
|
||||
macro_rules! indirect_line { () => ( line!() ) }
|
||||
|
||||
pub fn main() {
|
||||
assert_eq!(line!(), 17);
|
||||
assert_eq!(line!(), 16);
|
||||
assert_eq!(column!(), 16);
|
||||
assert_eq!(indirect_line!(), 19);
|
||||
assert_eq!(indirect_line!(), 18);
|
||||
assert!((file!().ends_with("syntax-extension-source-utils.rs")));
|
||||
assert_eq!(stringify!((2*3) + 5).to_string(), "(2 * 3) + 5".to_string());
|
||||
assert!(include!("syntax-extension-source-utils-files/includeme.\
|
||||
@ -33,5 +32,5 @@ pub fn main() {
|
||||
// The Windows tests are wrapped in an extra module for some reason
|
||||
assert!((m1::m2::where_am_i().ends_with("m1::m2")));
|
||||
|
||||
assert_eq!((36, "(2 * 3) + 5"), (line!(), stringify!((2*3) + 5)));
|
||||
assert_eq!((35, "(2 * 3) + 5"), (line!(), stringify!((2*3) + 5)));
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
// run-pass
|
||||
// ignore-pretty issue #37195
|
||||
|
||||
mod mod_dir_implicit_aux;
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
// run-pass
|
||||
#![allow(unused_macros)]
|
||||
// ignore-pretty issue #37195
|
||||
|
||||
mod mod_dir_simple {
|
||||
#[path = "test.rs"]
|
||||
|
@ -1,5 +1,4 @@
|
||||
// run-pass
|
||||
// ignore-pretty issue #37195
|
||||
|
||||
#[path = "mod_dir_simple"]
|
||||
mod pancakes {
|
||||
|
@ -1,5 +1,4 @@
|
||||
// run-pass
|
||||
// ignore-pretty issue #37195
|
||||
|
||||
#[path = "mod_dir_simple"]
|
||||
mod pancakes {
|
||||
|
@ -1,5 +1,4 @@
|
||||
// run-pass
|
||||
// ignore-pretty issue #37195
|
||||
|
||||
#[path = "mod_dir_simple"]
|
||||
mod biscuits {
|
||||
|
@ -1,5 +1,4 @@
|
||||
// run-pass
|
||||
// ignore-pretty issue #37195
|
||||
|
||||
// Testing that the parser for each file tracks its modules
|
||||
// and paths independently. The load_another_mod module should
|
||||
|
@ -1,5 +1,4 @@
|
||||
// run-pass
|
||||
// ignore-pretty issue #37195
|
||||
|
||||
mod mod_dir_simple {
|
||||
pub mod test;
|
||||
|
@ -1,5 +1,4 @@
|
||||
// run-pass
|
||||
// ignore-pretty issue #37195
|
||||
|
||||
// Testing that a plain .rs file can load modules from other source files
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
// run-pass
|
||||
// ignore-pretty issue #37195
|
||||
|
||||
// Testing that a plain .rs file can load modules from other source files
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
// run-pass
|
||||
//
|
||||
// ignore-pretty issue #37195
|
||||
pub mod modrs_mod;
|
||||
pub mod foors_mod;
|
||||
#[path = "some_crazy_attr_mod_dir/arbitrary_name.rs"]
|
||||
|
@ -7,7 +7,6 @@
|
||||
// issue-48508-aux.rs
|
||||
|
||||
// compile-flags:-g
|
||||
// ignore-pretty issue #37195
|
||||
// ignore-asmjs wasm2js does not support source maps yet
|
||||
|
||||
#![allow(uncommon_codepoints)]
|
||||
|
@ -1,5 +1,4 @@
|
||||
// run-pass
|
||||
// ignore-pretty
|
||||
// aux-build:span-api-tests.rs
|
||||
// aux-build:span-test-macros.rs
|
||||
// compile-flags: -Ztranslate-remapped-path-to-local-path=yes
|
||||
|
@ -9,7 +9,6 @@
|
||||
// compile-flags:-g -Copt-level=0 -Cllvm-args=-enable-tail-merge=0
|
||||
// compile-flags:-Cforce-frame-pointers=yes
|
||||
// compile-flags:-Cstrip=none
|
||||
// ignore-pretty issue #37195
|
||||
// ignore-emscripten spawning processes is not supported
|
||||
// ignore-sgx no processes
|
||||
// ignore-fuchsia Backtrace not symbolized, trace different line alignment
|
||||
|
@ -1,5 +1,7 @@
|
||||
// build-pass
|
||||
// only-x86-windows
|
||||
// only-x86
|
||||
// only-windows
|
||||
// ignore-gnu - vectorcall is not supported by GCC: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89485
|
||||
#![crate_type = "cdylib"]
|
||||
#![feature(abi_vectorcall)]
|
||||
|
||||
|
@ -6,7 +6,6 @@
|
||||
// ignore-mips64
|
||||
// ignore-powerpc
|
||||
// ignore-powerpc64
|
||||
// ignore-powerpc64le
|
||||
// ignore-riscv64
|
||||
// ignore-sparc
|
||||
// ignore-sparc64
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0658]: the target feature `avx512bw` is currently unstable
|
||||
--> $DIR/gate.rs:32:18
|
||||
--> $DIR/gate.rs:31:18
|
||||
|
|
||||
LL | #[target_feature(enable = "avx512bw")]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -6,7 +6,6 @@
|
||||
// ignore-mips64
|
||||
// ignore-powerpc
|
||||
// ignore-powerpc64
|
||||
// ignore-powerpc64le
|
||||
// ignore-riscv64
|
||||
// ignore-s390x
|
||||
// ignore-sparc
|
||||
|
@ -1,11 +1,11 @@
|
||||
error: malformed `target_feature` attribute input
|
||||
--> $DIR/invalid-attribute.rs:32:1
|
||||
--> $DIR/invalid-attribute.rs:31:1
|
||||
|
|
||||
LL | #[target_feature = "+sse2"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[target_feature(enable = "name")]`
|
||||
|
||||
error: attribute should be applied to a function definition
|
||||
--> $DIR/invalid-attribute.rs:17:1
|
||||
--> $DIR/invalid-attribute.rs:16:1
|
||||
|
|
||||
LL | #[target_feature(enable = "sse2")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -14,7 +14,7 @@ LL | extern crate alloc;
|
||||
| ------------------- not a function definition
|
||||
|
||||
error: attribute should be applied to a function definition
|
||||
--> $DIR/invalid-attribute.rs:22:1
|
||||
--> $DIR/invalid-attribute.rs:21:1
|
||||
|
|
||||
LL | #[target_feature(enable = "sse2")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -23,7 +23,7 @@ LL | use alloc::alloc::alloc;
|
||||
| ------------------------ not a function definition
|
||||
|
||||
error: attribute should be applied to a function definition
|
||||
--> $DIR/invalid-attribute.rs:27:1
|
||||
--> $DIR/invalid-attribute.rs:26:1
|
||||
|
|
||||
LL | #[target_feature(enable = "sse2")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -32,7 +32,7 @@ LL | extern "Rust" {}
|
||||
| ---------------- not a function definition
|
||||
|
||||
error: attribute should be applied to a function definition
|
||||
--> $DIR/invalid-attribute.rs:49:1
|
||||
--> $DIR/invalid-attribute.rs:48:1
|
||||
|
|
||||
LL | #[target_feature(enable = "sse2")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -41,7 +41,7 @@ LL | mod another {}
|
||||
| -------------- not a function definition
|
||||
|
||||
error: attribute should be applied to a function definition
|
||||
--> $DIR/invalid-attribute.rs:54:1
|
||||
--> $DIR/invalid-attribute.rs:53:1
|
||||
|
|
||||
LL | #[target_feature(enable = "sse2")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -50,7 +50,7 @@ LL | const FOO: usize = 7;
|
||||
| --------------------- not a function definition
|
||||
|
||||
error: attribute should be applied to a function definition
|
||||
--> $DIR/invalid-attribute.rs:59:1
|
||||
--> $DIR/invalid-attribute.rs:58:1
|
||||
|
|
||||
LL | #[target_feature(enable = "sse2")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -59,7 +59,7 @@ LL | struct Foo;
|
||||
| ----------- not a function definition
|
||||
|
||||
error: attribute should be applied to a function definition
|
||||
--> $DIR/invalid-attribute.rs:64:1
|
||||
--> $DIR/invalid-attribute.rs:63:1
|
||||
|
|
||||
LL | #[target_feature(enable = "sse2")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -68,7 +68,7 @@ LL | enum Bar {}
|
||||
| ----------- not a function definition
|
||||
|
||||
error: attribute should be applied to a function definition
|
||||
--> $DIR/invalid-attribute.rs:69:1
|
||||
--> $DIR/invalid-attribute.rs:68:1
|
||||
|
|
||||
LL | #[target_feature(enable = "sse2")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -81,7 +81,7 @@ LL | | }
|
||||
| |_- not a function definition
|
||||
|
||||
error: attribute should be applied to a function definition
|
||||
--> $DIR/invalid-attribute.rs:77:1
|
||||
--> $DIR/invalid-attribute.rs:76:1
|
||||
|
|
||||
LL | #[target_feature(enable = "sse2")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -90,7 +90,7 @@ LL | type Uwu = ();
|
||||
| -------------- not a function definition
|
||||
|
||||
error: attribute should be applied to a function definition
|
||||
--> $DIR/invalid-attribute.rs:82:1
|
||||
--> $DIR/invalid-attribute.rs:81:1
|
||||
|
|
||||
LL | #[target_feature(enable = "sse2")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -99,7 +99,7 @@ LL | trait Baz {}
|
||||
| ------------ not a function definition
|
||||
|
||||
error: attribute should be applied to a function definition
|
||||
--> $DIR/invalid-attribute.rs:92:1
|
||||
--> $DIR/invalid-attribute.rs:91:1
|
||||
|
|
||||
LL | #[target_feature(enable = "sse2")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -108,7 +108,7 @@ LL | static A: () = ();
|
||||
| ------------------ not a function definition
|
||||
|
||||
error: attribute should be applied to a function definition
|
||||
--> $DIR/invalid-attribute.rs:97:1
|
||||
--> $DIR/invalid-attribute.rs:96:1
|
||||
|
|
||||
LL | #[target_feature(enable = "sse2")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -117,7 +117,7 @@ LL | impl Quux for u8 {}
|
||||
| ------------------- not a function definition
|
||||
|
||||
error: attribute should be applied to a function definition
|
||||
--> $DIR/invalid-attribute.rs:102:1
|
||||
--> $DIR/invalid-attribute.rs:101:1
|
||||
|
|
||||
LL | #[target_feature(enable = "sse2")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -126,7 +126,7 @@ LL | impl Foo {}
|
||||
| ----------- not a function definition
|
||||
|
||||
error: attribute should be applied to a function definition
|
||||
--> $DIR/invalid-attribute.rs:120:5
|
||||
--> $DIR/invalid-attribute.rs:119:5
|
||||
|
|
||||
LL | #[target_feature(enable = "sse2")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -138,7 +138,7 @@ LL | | }
|
||||
| |_____- not a function definition
|
||||
|
||||
error: attribute should be applied to a function definition
|
||||
--> $DIR/invalid-attribute.rs:128:5
|
||||
--> $DIR/invalid-attribute.rs:127:5
|
||||
|
|
||||
LL | #[target_feature(enable = "sse2")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -147,25 +147,25 @@ LL | || {};
|
||||
| ----- not a function definition
|
||||
|
||||
error: the feature named `foo` is not valid for this target
|
||||
--> $DIR/invalid-attribute.rs:34:18
|
||||
--> $DIR/invalid-attribute.rs:33:18
|
||||
|
|
||||
LL | #[target_feature(enable = "foo")]
|
||||
| ^^^^^^^^^^^^^^ `foo` is not valid for this target
|
||||
|
||||
error: malformed `target_feature` attribute input
|
||||
--> $DIR/invalid-attribute.rs:37:18
|
||||
--> $DIR/invalid-attribute.rs:36:18
|
||||
|
|
||||
LL | #[target_feature(bar)]
|
||||
| ^^^ help: must be of the form: `enable = ".."`
|
||||
|
||||
error: malformed `target_feature` attribute input
|
||||
--> $DIR/invalid-attribute.rs:39:18
|
||||
--> $DIR/invalid-attribute.rs:38:18
|
||||
|
|
||||
LL | #[target_feature(disable = "baz")]
|
||||
| ^^^^^^^^^^^^^^^ help: must be of the form: `enable = ".."`
|
||||
|
||||
error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions
|
||||
--> $DIR/invalid-attribute.rs:43:1
|
||||
--> $DIR/invalid-attribute.rs:42:1
|
||||
|
|
||||
LL | #[target_feature(enable = "sse2")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -177,13 +177,13 @@ LL | fn bar() {}
|
||||
= help: add `#![feature(target_feature_11)]` to the crate attributes to enable
|
||||
|
||||
error: cannot use `#[inline(always)]` with `#[target_feature]`
|
||||
--> $DIR/invalid-attribute.rs:87:1
|
||||
--> $DIR/invalid-attribute.rs:86:1
|
||||
|
|
||||
LL | #[inline(always)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions
|
||||
--> $DIR/invalid-attribute.rs:112:5
|
||||
--> $DIR/invalid-attribute.rs:111:5
|
||||
|
|
||||
LL | #[target_feature(enable = "sse2")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -1,5 +1,4 @@
|
||||
// run-pass
|
||||
// ignore-pretty `dyn ::foo` parses differently in the current edition
|
||||
|
||||
use std::fmt::Display;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user