mirror of
https://github.com/rust-lang/rust
synced 2024-09-06 01:11:17 +00:00
add support for blessing panic=abort mir-opt tests
This commit is contained in:
parent
9ec370d40c
commit
9de3c29319
|
@ -429,6 +429,7 @@ fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|||
pub struct TargetSelection {
|
||||
pub triple: Interned<String>,
|
||||
file: Option<Interned<String>>,
|
||||
synthetic: bool,
|
||||
}
|
||||
|
||||
/// Newtype over `Vec<TargetSelection>` so we can implement custom parsing logic
|
||||
|
@ -460,7 +461,15 @@ pub fn from_user(selection: &str) -> Self {
|
|||
let triple = INTERNER.intern_str(triple);
|
||||
let file = file.map(|f| INTERNER.intern_str(f));
|
||||
|
||||
Self { triple, file }
|
||||
Self { triple, file, synthetic: false }
|
||||
}
|
||||
|
||||
pub fn create_synthetic(triple: &str, file: &str) -> Self {
|
||||
Self {
|
||||
triple: INTERNER.intern_str(triple),
|
||||
file: Some(INTERNER.intern_str(file)),
|
||||
synthetic: true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rustc_target_arg(&self) -> &str {
|
||||
|
@ -478,6 +487,11 @@ pub fn starts_with(&self, needle: &str) -> bool {
|
|||
pub fn ends_with(&self, needle: &str) -> bool {
|
||||
self.triple.ends_with(needle)
|
||||
}
|
||||
|
||||
// See src/bootstrap/synthetic_targets.rs
|
||||
pub fn is_synthetic(&self) -> bool {
|
||||
self.synthetic
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for TargetSelection {
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
mod sanity;
|
||||
mod setup;
|
||||
mod suggest;
|
||||
mod synthetic_targets;
|
||||
mod tarball;
|
||||
mod test;
|
||||
mod tool;
|
||||
|
|
82
src/bootstrap/synthetic_targets.rs
Normal file
82
src/bootstrap/synthetic_targets.rs
Normal file
|
@ -0,0 +1,82 @@
|
|||
//! In some cases, parts of bootstrap need to change part of a target spec just for one or a few
|
||||
//! steps. Adding these targets to rustc proper would "leak" this implementation detail of
|
||||
//! bootstrap, and would make it more complex to apply additional changes if the need arises.
|
||||
//!
|
||||
//! To address that problem, this module implements support for "synthetic targets". Synthetic
|
||||
//! targets are custom target specs generated using builtin target specs as their base. You can use
|
||||
//! one of the target specs already defined in this module, or create new ones by adding a new step
|
||||
//! that calls create_synthetic_target.
|
||||
|
||||
use crate::builder::{Builder, ShouldRun, Step};
|
||||
use crate::config::TargetSelection;
|
||||
use crate::Compiler;
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct MirOptPanicAbortSyntheticTarget {
|
||||
pub(crate) compiler: Compiler,
|
||||
pub(crate) base: TargetSelection,
|
||||
}
|
||||
|
||||
impl Step for MirOptPanicAbortSyntheticTarget {
|
||||
type Output = TargetSelection;
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = false;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
run.never()
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) -> Self::Output {
|
||||
create_synthetic_target(builder, self.compiler, "miropt-abort", self.base, |spec| {
|
||||
spec.insert("panic-strategy".into(), "abort".into());
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn create_synthetic_target(
|
||||
builder: &Builder<'_>,
|
||||
compiler: Compiler,
|
||||
suffix: &str,
|
||||
base: TargetSelection,
|
||||
customize: impl FnOnce(&mut serde_json::Map<String, serde_json::Value>),
|
||||
) -> TargetSelection {
|
||||
if base.contains("synthetic") {
|
||||
// This check is not strictly needed, but nothing currently needs recursive synthetic
|
||||
// targets. If the need arises, removing this in the future *SHOULD* be safe.
|
||||
panic!("cannot create synthetic targets with other synthetic targets as their base");
|
||||
}
|
||||
|
||||
let name = format!("{base}-synthetic-{suffix}");
|
||||
let path = builder.out.join("synthetic-target-specs").join(format!("{name}.json"));
|
||||
std::fs::create_dir_all(path.parent().unwrap()).unwrap();
|
||||
|
||||
if builder.config.dry_run() {
|
||||
std::fs::write(&path, b"dry run\n").unwrap();
|
||||
return TargetSelection::create_synthetic(&name, path.to_str().unwrap());
|
||||
}
|
||||
|
||||
let mut cmd = Command::new(builder.rustc(compiler));
|
||||
cmd.arg("--target").arg(base.rustc_target_arg());
|
||||
cmd.args(["-Zunstable-options", "--print", "target-spec-json"]);
|
||||
cmd.stdout(Stdio::piped());
|
||||
|
||||
let output = cmd.spawn().unwrap().wait_with_output().unwrap();
|
||||
if !output.status.success() {
|
||||
panic!("failed to gather the target spec for {base}");
|
||||
}
|
||||
|
||||
let mut spec: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap();
|
||||
let spec_map = spec.as_object_mut().unwrap();
|
||||
|
||||
// The `is-builtin` attribute of a spec needs to be removed, otherwise rustc will complain.
|
||||
spec_map.remove("is-builtin");
|
||||
|
||||
customize(spec_map);
|
||||
|
||||
std::fs::write(&path, &serde_json::to_vec_pretty(&spec).unwrap()).unwrap();
|
||||
let target = TargetSelection::create_synthetic(&name, path.to_str().unwrap());
|
||||
crate::cc_detect::find_target(builder, target);
|
||||
|
||||
target
|
||||
}
|
|
@ -23,6 +23,7 @@
|
|||
use crate::flags::Subcommand;
|
||||
use crate::llvm;
|
||||
use crate::render_tests::add_flags_and_try_run_tests;
|
||||
use crate::synthetic_targets::MirOptPanicAbortSyntheticTarget;
|
||||
use crate::tool::{self, SourceType, Tool};
|
||||
use crate::toolstate::ToolState;
|
||||
use crate::util::{self, add_link_lib_path, dylib_path, dylib_path_var, output, t, up_to_date};
|
||||
|
@ -1347,8 +1348,8 @@ fn run(self, builder: &Builder<'_>) {
|
|||
};
|
||||
|
||||
// We use custom logic to bless the mir-opt suite: mir-opt tests have multiple variants
|
||||
// (32bit vs 64bit), and all of them needs to be blessed. When blessing, we try best-effort
|
||||
// to also bless the other variants, to aid developers.
|
||||
// (32bit vs 64bit, and panic=abort vs panic=unwind), and all of them needs to be blessed.
|
||||
// When blessing, we try best-effort to also bless the other variants, to aid developers.
|
||||
if builder.config.cmd.bless() {
|
||||
let targets = MIR_OPT_BLESS_TARGET_MAPPING
|
||||
.iter()
|
||||
|
@ -1385,6 +1386,12 @@ fn run(self, builder: &Builder<'_>) {
|
|||
|
||||
for target in targets {
|
||||
run(target);
|
||||
|
||||
let panic_abort_target = builder.ensure(MirOptPanicAbortSyntheticTarget {
|
||||
compiler: self.compiler,
|
||||
base: target,
|
||||
});
|
||||
run(panic_abort_target);
|
||||
}
|
||||
} else {
|
||||
run(self.target);
|
||||
|
|
Loading…
Reference in a new issue