Skip to content

Commit 7a45322

Browse files
authored
Rollup merge of #125286 - RalfJung:miri-sync, r=RalfJung
Miri subtree update r? `@ghost`
2 parents 131d48f + e93268e commit 7a45322

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1298
-606
lines changed

Cargo.lock

+2-2
Original file line numberDiff line numberDiff line change
@@ -3426,9 +3426,9 @@ dependencies = [
34263426

34273427
[[package]]
34283428
name = "rustc-build-sysroot"
3429-
version = "0.4.7"
3429+
version = "0.5.2"
34303430
source = "registry+https://github.com/rust-lang/crates.io-index"
3431-
checksum = "ab1dbbd1bdf65fdac44c885f6cca147ba179108ce284b60a08ccc04b1f1dbac0"
3431+
checksum = "fa3ca63cc537c1cb69e4c2c0afc5fda2ccd36ac84c97d5a4ae05e69b1c834afb"
34323432
dependencies = [
34333433
"anyhow",
34343434
"rustc_version",

src/tools/miri/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ tex/*/out
55
*.out
66
*.rs.bk
77
.vscode
8+
.helix
89
*.mm_profdata
910
perf.data
1011
perf.data.old

src/tools/miri/cargo-miri/Cargo.lock

+2-2
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,9 @@ dependencies = [
178178

179179
[[package]]
180180
name = "rustc-build-sysroot"
181-
version = "0.4.7"
181+
version = "0.5.2"
182182
source = "registry+https://github.com/rust-lang/crates.io-index"
183-
checksum = "ab1dbbd1bdf65fdac44c885f6cca147ba179108ce284b60a08ccc04b1f1dbac0"
183+
checksum = "fa3ca63cc537c1cb69e4c2c0afc5fda2ccd36ac84c97d5a4ae05e69b1c834afb"
184184
dependencies = [
185185
"anyhow",
186186
"rustc_version",

src/tools/miri/cargo-miri/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ directories = "5"
1818
rustc_version = "0.4"
1919
serde_json = "1.0.40"
2020
cargo_metadata = "0.18.0"
21-
rustc-build-sysroot = "0.4.6"
21+
rustc-build-sysroot = "0.5.2"
2222

2323
# Enable some feature flags that dev-dependencies need but dependencies
2424
# do not. This makes `./miri install` after `./miri build` faster.

src/tools/miri/cargo-miri/src/setup.rs

+44-43
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22
33
use std::env;
44
use std::ffi::OsStr;
5-
use std::fmt::Write;
65
use std::path::PathBuf;
76
use std::process::{self, Command};
87

9-
use rustc_build_sysroot::{BuildMode, SysrootBuilder, SysrootConfig};
8+
use rustc_build_sysroot::{BuildMode, SysrootBuilder, SysrootConfig, SysrootStatus};
109
use rustc_version::VersionMeta;
1110

1211
use crate::util::*;
@@ -24,6 +23,7 @@ pub fn setup(
2423
let only_setup = matches!(subcommand, MiriCommand::Setup);
2524
let ask_user = !only_setup;
2625
let print_sysroot = only_setup && has_arg_flag("--print-sysroot"); // whether we just print the sysroot path
26+
let show_setup = only_setup && !print_sysroot;
2727
if !only_setup {
2828
if let Some(sysroot) = std::env::var_os("MIRI_SYSROOT") {
2929
// Skip setup step if MIRI_SYSROOT is explicitly set, *unless* we are `cargo miri setup`.
@@ -115,18 +115,16 @@ pub fn setup(
115115
// `config.toml`.
116116
command.env("RUSTC_WRAPPER", "");
117117

118-
if only_setup && !print_sysroot {
118+
if show_setup {
119119
// Forward output. Even make it verbose, if requested.
120+
command.stdout(process::Stdio::inherit());
121+
command.stderr(process::Stdio::inherit());
120122
for _ in 0..verbose {
121123
command.arg("-v");
122124
}
123125
if quiet {
124126
command.arg("--quiet");
125127
}
126-
} else {
127-
// Suppress output.
128-
command.stdout(process::Stdio::null());
129-
command.stderr(process::Stdio::null());
130128
}
131129

132130
command
@@ -137,49 +135,52 @@ pub fn setup(
137135
// not apply `RUSTFLAGS` to the sysroot either.
138136
let rustflags = &["-Cdebug-assertions=off", "-Coverflow-checks=on"];
139137

140-
// Do the build.
141-
if print_sysroot || quiet {
142-
// Be silent.
143-
} else {
144-
let mut msg = String::new();
145-
write!(msg, "Preparing a sysroot for Miri (target: {target})").unwrap();
146-
if verbose > 0 {
147-
write!(msg, " in {}", sysroot_dir.display()).unwrap();
148-
}
149-
write!(msg, "...").unwrap();
150-
if only_setup {
151-
// We want to be explicit.
152-
eprintln!("{msg}");
153-
} else {
154-
// We want to be quiet, but still let the user know that something is happening.
155-
eprint!("{msg} ");
138+
let mut after_build_output = String::new(); // what should be printed when the build is done.
139+
let notify = || {
140+
if !quiet {
141+
eprint!("Preparing a sysroot for Miri (target: {target})");
142+
if verbose > 0 {
143+
eprint!(" in {}", sysroot_dir.display());
144+
}
145+
if show_setup {
146+
// Cargo will print things, so we need to finish this line.
147+
eprintln!("...");
148+
after_build_output = format!(
149+
"A sysroot for Miri is now available in `{}`.\n",
150+
sysroot_dir.display()
151+
);
152+
} else {
153+
// Keep all output on a single line.
154+
eprint!("... ");
155+
after_build_output = format!("done\n");
156+
}
156157
}
157-
}
158-
SysrootBuilder::new(&sysroot_dir, target)
158+
};
159+
160+
// Do the build.
161+
let status = SysrootBuilder::new(&sysroot_dir, target)
159162
.build_mode(BuildMode::Check)
160163
.rustc_version(rustc_version.clone())
161164
.sysroot_config(sysroot_config)
162165
.rustflags(rustflags)
163166
.cargo(cargo_cmd)
164-
.build_from_source(&rust_src)
165-
.unwrap_or_else(|err| {
166-
if print_sysroot {
167-
show_error!("failed to build sysroot")
168-
} else if only_setup {
169-
show_error!("failed to build sysroot: {err:?}")
170-
} else {
171-
show_error!(
172-
"failed to build sysroot; run `cargo miri setup` to see the error details"
173-
)
174-
}
175-
});
176-
if print_sysroot || quiet {
177-
// Be silent.
178-
} else if only_setup {
179-
eprintln!("A sysroot for Miri is now available in `{}`.", sysroot_dir.display());
180-
} else {
181-
eprintln!("done");
167+
.when_build_required(notify)
168+
.build_from_source(&rust_src);
169+
match status {
170+
Ok(SysrootStatus::AlreadyCached) =>
171+
if !quiet && show_setup {
172+
eprintln!(
173+
"A sysroot for Miri is already available in `{}`.",
174+
sysroot_dir.display()
175+
);
176+
},
177+
Ok(SysrootStatus::SysrootBuilt) => {
178+
// Print what `notify` prepared.
179+
eprint!("{after_build_output}");
180+
}
181+
Err(err) => show_error!("failed to build sysroot: {err:?}"),
182182
}
183+
183184
if print_sysroot {
184185
// Print just the sysroot and nothing else to stdout; this way we do not need any escaping.
185186
println!("{}", sysroot_dir.display());

src/tools/miri/ci/ci.sh

+10-10
Original file line numberDiff line numberDiff line change
@@ -144,16 +144,16 @@ case $HOST_TARGET in
144144
TEST_TARGET=arm-unknown-linux-gnueabi run_tests
145145
TEST_TARGET=s390x-unknown-linux-gnu run_tests # big-endian architecture of choice
146146
# Partially supported targets (tier 2)
147-
VERY_BASIC="integer vec string btreemap" # common things we test on all of them (if they have std), requires no target-specific shims
148-
BASIC="$VERY_BASIC hello hashmap alloc align" # ensures we have the shims for stdout and basic data structures
149-
TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC panic/panic concurrency/simple atomic threadname libc-mem libc-misc libc-random libc-time fs env num_cpus
150-
TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC panic/panic concurrency/simple atomic threadname libc-mem libc-misc libc-random libc-time fs env num_cpus
151-
TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $VERY_BASIC hello panic/panic concurrency/simple pthread-sync libc-mem libc-misc libc-random
152-
TEST_TARGET=x86_64-pc-solaris run_tests_minimal $VERY_BASIC hello panic/panic concurrency/simple pthread-sync libc-mem libc-misc libc-random
153-
TEST_TARGET=aarch64-linux-android run_tests_minimal $VERY_BASIC hello panic/panic
154-
TEST_TARGET=wasm32-wasi run_tests_minimal $VERY_BASIC wasm
155-
TEST_TARGET=wasm32-unknown-unknown run_tests_minimal $VERY_BASIC wasm
156-
TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std
147+
BASIC="empty_main integer vec string btreemap hello hashmap heap_alloc align" # ensures we have the basics: stdout/stderr, system allocator, randomness (for HashMap initialization)
148+
UNIX="panic/panic panic/unwind concurrency/simple atomic libc-mem libc-misc libc-random env num_cpus" # the things that are very similar across all Unixes, and hence easily supported there
149+
TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC $UNIX threadname libc-time fs
150+
TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC $UNIX threadname libc-time fs
151+
TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $BASIC $UNIX pthread-sync
152+
TEST_TARGET=x86_64-pc-solaris run_tests_minimal $BASIC $UNIX pthread-sync
153+
TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX
154+
TEST_TARGET=wasm32-wasip2 run_tests_minimal empty_main wasm heap_alloc libc-mem
155+
TEST_TARGET=wasm32-unknown-unknown run_tests_minimal empty_main wasm
156+
TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std
157157
# Custom target JSON file
158158
TEST_TARGET=tests/avr.json MIRI_NO_STD=1 run_tests_minimal no_std
159159
;;
+136
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
use std::env;
2+
use std::iter;
3+
4+
use anyhow::{bail, Result};
5+
6+
pub struct Args {
7+
args: iter::Peekable<env::Args>,
8+
/// Set to `true` once we saw a `--`.
9+
terminated: bool,
10+
}
11+
12+
impl Args {
13+
pub fn new() -> Self {
14+
let mut args = Args { args: env::args().peekable(), terminated: false };
15+
args.args.next().unwrap(); // skip program name
16+
args
17+
}
18+
19+
/// Get the next argument without any interpretation.
20+
pub fn next_raw(&mut self) -> Option<String> {
21+
self.args.next()
22+
}
23+
24+
/// Consume a `-$f` flag if present.
25+
pub fn get_short_flag(&mut self, flag: char) -> Result<bool> {
26+
if self.terminated {
27+
return Ok(false);
28+
}
29+
if let Some(next) = self.args.peek() {
30+
if let Some(next) = next.strip_prefix("-") {
31+
if let Some(next) = next.strip_prefix(flag) {
32+
if next.is_empty() {
33+
self.args.next().unwrap(); // consume this argument
34+
return Ok(true);
35+
} else {
36+
bail!("`-{flag}` followed by value");
37+
}
38+
}
39+
}
40+
}
41+
Ok(false)
42+
}
43+
44+
/// Consume a `--$name` flag if present.
45+
pub fn get_long_flag(&mut self, name: &str) -> Result<bool> {
46+
if self.terminated {
47+
return Ok(false);
48+
}
49+
if let Some(next) = self.args.peek() {
50+
if let Some(next) = next.strip_prefix("--") {
51+
if next == name {
52+
self.args.next().unwrap(); // consume this argument
53+
return Ok(true);
54+
}
55+
}
56+
}
57+
Ok(false)
58+
}
59+
60+
/// Consume a `--$name val` or `--$name=val` option if present.
61+
pub fn get_long_opt(&mut self, name: &str) -> Result<Option<String>> {
62+
assert!(!name.is_empty());
63+
if self.terminated {
64+
return Ok(None);
65+
}
66+
let Some(next) = self.args.peek() else { return Ok(None) };
67+
let Some(next) = next.strip_prefix("--") else { return Ok(None) };
68+
let Some(next) = next.strip_prefix(name) else { return Ok(None) };
69+
// Starts with `--flag`.
70+
Ok(if let Some(val) = next.strip_prefix("=") {
71+
// `--flag=val` form
72+
let val = val.into();
73+
self.args.next().unwrap(); // consume this argument
74+
Some(val)
75+
} else if next.is_empty() {
76+
// `--flag val` form
77+
self.args.next().unwrap(); // consume this argument
78+
let Some(val) = self.args.next() else { bail!("`--{name}` not followed by value") };
79+
Some(val)
80+
} else {
81+
// Some unrelated flag, like `--flag-more` or so.
82+
None
83+
})
84+
}
85+
86+
/// Consume a `--$name=val` or `--$name` option if present; the latter
87+
/// produces a default value. (`--$name val` is *not* accepted for this form
88+
/// of argument, it understands `val` already as the next argument!)
89+
pub fn get_long_opt_with_default(
90+
&mut self,
91+
name: &str,
92+
default: &str,
93+
) -> Result<Option<String>> {
94+
assert!(!name.is_empty());
95+
if self.terminated {
96+
return Ok(None);
97+
}
98+
let Some(next) = self.args.peek() else { return Ok(None) };
99+
let Some(next) = next.strip_prefix("--") else { return Ok(None) };
100+
let Some(next) = next.strip_prefix(name) else { return Ok(None) };
101+
// Starts with `--flag`.
102+
Ok(if let Some(val) = next.strip_prefix("=") {
103+
// `--flag=val` form
104+
let val = val.into();
105+
self.args.next().unwrap(); // consume this argument
106+
Some(val)
107+
} else if next.is_empty() {
108+
// `--flag` form
109+
self.args.next().unwrap(); // consume this argument
110+
Some(default.into())
111+
} else {
112+
// Some unrelated flag, like `--flag-more` or so.
113+
None
114+
})
115+
}
116+
117+
/// Returns the next free argument or uninterpreted flag, or `None` if there are no more
118+
/// arguments left. `--` is returned as well, but it is interpreted in the sense that no more
119+
/// flags will be parsed after this.
120+
pub fn get_other(&mut self) -> Option<String> {
121+
if self.terminated {
122+
return self.args.next();
123+
}
124+
let next = self.args.next()?;
125+
if next == "--" {
126+
self.terminated = true; // don't parse any more flags
127+
// This is where our parser is special, we do yield the `--`.
128+
}
129+
Some(next)
130+
}
131+
132+
/// Return the rest of the aguments entirely unparsed.
133+
pub fn remainder(self) -> Vec<String> {
134+
self.args.collect()
135+
}
136+
}

0 commit comments

Comments
 (0)