Skip to content

Commit 00367d5

Browse files
committed
Auto merge of rust-lang#131727 - RalfJung:miri-sync, r=RalfJung
Miri subtree update r? `@ghost`
2 parents 88f3114 + 1f501a7 commit 00367d5

File tree

74 files changed

+1355
-878
lines changed

Some content is hidden

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

74 files changed

+1355
-878
lines changed

Cargo.lock

+8-2
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ dependencies = [
377377
"cargo_metadata",
378378
"directories",
379379
"rustc-build-sysroot",
380-
"rustc_tools_util",
380+
"rustc_tools_util 0.4.0",
381381
"rustc_version",
382382
"serde",
383383
"serde_json",
@@ -552,7 +552,7 @@ dependencies = [
552552
"parking_lot",
553553
"quote",
554554
"regex",
555-
"rustc_tools_util",
555+
"rustc_tools_util 0.3.0",
556556
"serde",
557557
"serde_json",
558558
"syn 2.0.79",
@@ -4465,6 +4465,12 @@ version = "0.3.0"
44654465
source = "registry+https://github.com/rust-lang/crates.io-index"
44664466
checksum = "8ba09476327c4b70ccefb6180f046ef588c26a24cf5d269a9feba316eb4f029f"
44674467

4468+
[[package]]
4469+
name = "rustc_tools_util"
4470+
version = "0.4.0"
4471+
source = "registry+https://github.com/rust-lang/crates.io-index"
4472+
checksum = "3316159ab19e19d1065ecc49278e87f767a9dae9fae80348d2b4d4fa4ae02d4d"
4473+
44684474
[[package]]
44694475
name = "rustc_trait_selection"
44704476
version = "0.0.0"

src/tools/miri/CONTRIBUTING.md

+36-39
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ process for such contributions:
4545
This process is largely informal, and its primary goal is to more clearly communicate expectations.
4646
Please get in touch with us if you have any questions!
4747

48+
### Managing the review state
49+
50+
Most PRs bounce back and forth between the reviewer and the author several times, so it is good to
51+
keep track of who is expected to take the next step. We are using the `S-waiting-for-review` and
52+
`S-waiting-for-author` labels for that. If a reviewer asked you to do some changes and you think
53+
they are all taken care of, post a comment saying `@rustbot ready` to mark a PR as ready for the
54+
next round of review.
55+
4856
## Preparing the build environment
4957

5058
Miri heavily relies on internal and unstable rustc interfaces to execute MIR,
@@ -195,48 +203,37 @@ installed (`cargo install hyperfine`).
195203

196204
## Configuring `rust-analyzer`
197205

198-
To configure `rust-analyzer` and VS Code for working on Miri, save the following
199-
to `.vscode/settings.json` in your local Miri clone:
200-
201-
```json
202-
{
203-
"rust-analyzer.rustc.source": "discover",
204-
"rust-analyzer.linkedProjects": [
205-
"Cargo.toml",
206-
"cargo-miri/Cargo.toml",
207-
"miri-script/Cargo.toml",
208-
],
209-
"rust-analyzer.check.invocationLocation": "root",
210-
"rust-analyzer.check.invocationStrategy": "once",
211-
"rust-analyzer.check.overrideCommand": [
212-
"env",
213-
"MIRI_AUTO_OPS=no",
214-
"./miri",
215-
"clippy", // make this `check` when working with a locally built rustc
216-
"--message-format=json",
217-
],
218-
// Contrary to what the name suggests, this also affects proc macros.
219-
"rust-analyzer.cargo.buildScripts.invocationLocation": "root",
220-
"rust-analyzer.cargo.buildScripts.invocationStrategy": "once",
221-
"rust-analyzer.cargo.buildScripts.overrideCommand": [
222-
"env",
223-
"MIRI_AUTO_OPS=no",
224-
"./miri",
225-
"check",
226-
"--message-format=json",
227-
],
228-
}
229-
```
206+
To configure `rust-analyzer` and the IDE for working on Miri, copy one of the provided
207+
configuration files according to the instructions below. You can also set up a symbolic
208+
link to keep the configuration in sync with our recommendations.
209+
210+
### Visual Studio Code
211+
212+
Copy [`etc/rust_analyzer_vscode.json`] to `.vscode/settings.json` in the project root directory.
213+
214+
[`etc/rust_analyzer_vscode.json`]: https://github.com/rust-lang/miri/blob/master/etc/rust_analyzer_vscode.json
215+
216+
### Helix
217+
218+
Copy [`etc/rust_analyzer_helix.toml`] to `.helix/languages.toml` in the project root directory.
219+
220+
Since working on Miri requires a custom toolchain, and Helix requires the language server
221+
to be installed with the toolchain, you have to run `./miri toolchain -c rust-analyzer`
222+
when installing the Miri toolchain. Alternatively, set the `RUSTUP_TOOLCHAIN` environment variable according to
223+
[the documentation](https://rust-analyzer.github.io/manual.html#toolchain).
224+
225+
[`etc/rust_analyzer_helix.toml`]: https://github.com/rust-lang/miri/blob/master/etc/rust_analyzer_helix.toml
226+
227+
### Advanced configuration
230228

231-
> #### Note
232-
>
233-
> If you are [building Miri with a locally built rustc][], set
234-
> `rust-analyzer.rustcSource` to the relative path from your Miri clone to the
235-
> root `Cargo.toml` of the locally built rustc. For example, the path might look
236-
> like `../rust/Cargo.toml`.
229+
If you are building Miri with a locally built rustc, set
230+
`rust-analyzer.rustcSource` to the relative path from your Miri clone to the
231+
root `Cargo.toml` of the locally built rustc. For example, the path might look
232+
like `../rust/Cargo.toml`. In addition to that, replace `clippy` by `check`
233+
in the `rust-analyzer.check.overrideCommand` setting.
237234

238235
See the rustc-dev-guide's docs on ["Configuring `rust-analyzer` for `rustc`"][rdg-r-a]
239-
for more information about configuring VS Code and `rust-analyzer`.
236+
for more information about configuring the IDE and `rust-analyzer`.
240237

241238
[rdg-r-a]: https://rustc-dev-guide.rust-lang.org/building/suggested.html#configuring-rust-analyzer-for-rustc
242239

src/tools/miri/README.md

+1-6
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ environment variable. We first document the most relevant and most commonly used
290290
* `-Zmiri-compare-exchange-weak-failure-rate=<rate>` changes the failure rate of
291291
`compare_exchange_weak` operations. The default is `0.8` (so 4 out of 5 weak ops will fail).
292292
You can change it to any value between `0.0` and `1.0`, where `1.0` means it
293-
will always fail and `0.0` means it will never fail. Note than setting it to
293+
will always fail and `0.0` means it will never fail. Note that setting it to
294294
`1.0` will likely cause hangs, since it means programs using
295295
`compare_exchange_weak` cannot make progress.
296296
* `-Zmiri-disable-isolation` disables host isolation. As a consequence,
@@ -392,11 +392,6 @@ to Miri failing to detect cases of undefined behavior in a program.
392392
but reports to the program that it did actually write. This is useful when you
393393
are not interested in the actual program's output, but only want to see Miri's
394394
errors and warnings.
395-
* `-Zmiri-panic-on-unsupported` will makes some forms of unsupported functionality,
396-
such as FFI and unsupported syscalls, panic within the context of the emulated
397-
application instead of raising an error within the context of Miri (and halting
398-
execution). Note that code might not expect these operations to ever panic, so
399-
this flag can lead to strange (mis)behavior.
400395
* `-Zmiri-recursive-validation` is a *highly experimental* flag that makes validity checking
401396
recurse below references.
402397
* `-Zmiri-retag-fields[=<all|none|scalar>]` controls when Stacked Borrows retagging recurses into

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# This file is automatically @generated by Cargo.
22
# It is not intended for manual editing.
3-
version = 3
3+
version = 4
44

55
[[package]]
66
name = "anyhow"
@@ -202,9 +202,9 @@ dependencies = [
202202

203203
[[package]]
204204
name = "rustc_tools_util"
205-
version = "0.3.0"
205+
version = "0.4.0"
206206
source = "registry+https://github.com/rust-lang/crates.io-index"
207-
checksum = "8ba09476327c4b70ccefb6180f046ef588c26a24cf5d269a9feba316eb4f029f"
207+
checksum = "3316159ab19e19d1065ecc49278e87f767a9dae9fae80348d2b4d4fa4ae02d4d"
208208

209209
[[package]]
210210
name = "rustc_version"

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,4 @@ rustc-build-sysroot = "0.5.4"
2626
serde = { version = "1.0.185", features = ["derive"] }
2727

2828
[build-dependencies]
29-
rustc_tools_util = "0.3"
29+
rustc_tools_util = "0.4"

src/tools/miri/ci/ci.sh

+4-4
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,10 @@ case $HOST_TARGET in
150150
# Partially supported targets (tier 2)
151151
BASIC="empty_main integer heap_alloc libc-mem vec string btreemap" # ensures we have the basics: pre-main code, system allocator
152152
UNIX="hello 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
153-
TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs
154-
TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs
155-
TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls
156-
TEST_TARGET=x86_64-pc-solaris run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls
153+
TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe
154+
TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe
155+
TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls libc-pipe
156+
TEST_TARGET=x86_64-pc-solaris run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls libc-pipe
157157
TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX time hashmap pthread --skip threadname
158158
TEST_TARGET=wasm32-wasip2 run_tests_minimal $BASIC wasm
159159
TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std empty_main wasm # this target doesn't really have std
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
[language-server.rust-analyzer.config.rustc]
2+
source = "discover"
3+
4+
[language-server.rust-analyzer.config]
5+
linkedProjects = [
6+
"Cargo.toml",
7+
"cargo-miri/Cargo.toml",
8+
"miri-script/Cargo.toml",
9+
]
10+
11+
[language-server.rust-analyzer.config.check]
12+
invocationLocation = "root"
13+
invocationStrategy = "once"
14+
overrideCommand = [
15+
"env",
16+
"MIRI_AUTO_OPS=no",
17+
"./miri",
18+
"clippy", # make this `check` when working with a locally built rustc
19+
"--message-format=json",
20+
]
21+
22+
# Contrary to what the name suggests, this also affects proc macros.
23+
[language-server.rust-analyzer.config.buildScripts]
24+
invocationLocation = "root"
25+
invocationStrategy = "once"
26+
overrideCommand = [
27+
"env",
28+
"MIRI_AUTO_OPS=no",
29+
"./miri",
30+
"check",
31+
"--message-format=json",
32+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"rust-analyzer.rustc.source": "discover",
3+
"rust-analyzer.linkedProjects": [
4+
"Cargo.toml",
5+
"cargo-miri/Cargo.toml",
6+
"miri-script/Cargo.toml",
7+
],
8+
"rust-analyzer.check.invocationLocation": "root",
9+
"rust-analyzer.check.invocationStrategy": "once",
10+
"rust-analyzer.check.overrideCommand": [
11+
"env",
12+
"MIRI_AUTO_OPS=no",
13+
"./miri",
14+
"clippy", // make this `check` when working with a locally built rustc
15+
"--message-format=json",
16+
],
17+
// Contrary to what the name suggests, this also affects proc macros.
18+
"rust-analyzer.cargo.buildScripts.invocationLocation": "root",
19+
"rust-analyzer.cargo.buildScripts.invocationStrategy": "once",
20+
"rust-analyzer.cargo.buildScripts.overrideCommand": [
21+
"env",
22+
"MIRI_AUTO_OPS=no",
23+
"./miri",
24+
"check",
25+
"--message-format=json",
26+
],
27+
}

src/tools/miri/rust-version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
7067e4aee45c18cfa1c6af3bf79bd097684fb294
1+
17a19e684cdf3ca088af8b4da6a6209d128913f4

src/tools/miri/src/alloc_addresses/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ impl<'tcx> MiriMachine<'tcx> {
453453
let thread = self.threads.active_thread();
454454
global_state.reuse.add_addr(rng, addr, size, align, kind, thread, || {
455455
if let Some(data_race) = &self.data_race {
456-
data_race.release_clock(&self.threads).clone()
456+
data_race.release_clock(&self.threads, |clock| clock.clone())
457457
} else {
458458
VClock::default()
459459
}

src/tools/miri/src/bin/miri.rs

-2
Original file line numberDiff line numberDiff line change
@@ -530,8 +530,6 @@ fn main() {
530530
} else if arg == "-Zmiri-ignore-leaks" {
531531
miri_config.ignore_leaks = true;
532532
miri_config.collect_leak_backtraces = false;
533-
} else if arg == "-Zmiri-panic-on-unsupported" {
534-
miri_config.panic_on_unsupported = true;
535533
} else if arg == "-Zmiri-strict-provenance" {
536534
miri_config.provenance_mode = ProvenanceMode::Strict;
537535
} else if arg == "-Zmiri-permissive-provenance" {

src/tools/miri/src/concurrency/data_race.rs

+17-16
Original file line numberDiff line numberDiff line change
@@ -828,15 +828,14 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> {
828828
}
829829
}
830830

831-
/// Returns the `release` clock of the current thread.
831+
/// Calls the callback with the "release" clock of the current thread.
832832
/// Other threads can acquire this clock in the future to establish synchronization
833833
/// with this program point.
834-
fn release_clock<'a>(&'a self) -> Option<Ref<'a, VClock>>
835-
where
836-
'tcx: 'a,
837-
{
834+
///
835+
/// The closure will only be invoked if data race handling is on.
836+
fn release_clock<R>(&self, callback: impl FnOnce(&VClock) -> R) -> Option<R> {
838837
let this = self.eval_context_ref();
839-
Some(this.machine.data_race.as_ref()?.release_clock(&this.machine.threads))
838+
Some(this.machine.data_race.as_ref()?.release_clock(&this.machine.threads, callback))
840839
}
841840

842841
/// Acquire the given clock into the current thread, establishing synchronization with
@@ -1728,7 +1727,7 @@ impl GlobalState {
17281727
let current_index = self.active_thread_index(thread_mgr);
17291728

17301729
// Store the terminaion clock.
1731-
let terminaion_clock = self.release_clock(thread_mgr).clone();
1730+
let terminaion_clock = self.release_clock(thread_mgr, |clock| clock.clone());
17321731
self.thread_info.get_mut()[current_thread].termination_vector_clock =
17331732
Some(terminaion_clock);
17341733

@@ -1778,21 +1777,23 @@ impl GlobalState {
17781777
clocks.clock.join(clock);
17791778
}
17801779

1781-
/// Returns the `release` clock of the current thread.
1780+
/// Calls the given closure with the "release" clock of the current thread.
17821781
/// Other threads can acquire this clock in the future to establish synchronization
17831782
/// with this program point.
1784-
pub fn release_clock<'tcx>(&self, threads: &ThreadManager<'tcx>) -> Ref<'_, VClock> {
1783+
pub fn release_clock<'tcx, R>(
1784+
&self,
1785+
threads: &ThreadManager<'tcx>,
1786+
callback: impl FnOnce(&VClock) -> R,
1787+
) -> R {
17851788
let thread = threads.active_thread();
17861789
let span = threads.active_thread_ref().current_span();
1787-
// We increment the clock each time this happens, to ensure no two releases
1788-
// can be confused with each other.
17891790
let (index, mut clocks) = self.thread_state_mut(thread);
1791+
let r = callback(&clocks.clock);
1792+
// Increment the clock, so that all following events cannot be confused with anything that
1793+
// occurred before the release. Crucially, the callback is invoked on the *old* clock!
17901794
clocks.increment_clock(index, span);
1791-
drop(clocks);
1792-
// To return a read-only view, we need to release the RefCell
1793-
// and borrow it again.
1794-
let (_index, clocks) = self.thread_state(thread);
1795-
Ref::map(clocks, |c| &c.clock)
1795+
1796+
r
17961797
}
17971798

17981799
fn thread_index(&self, thread: ThreadId) -> VectorIdx {

src/tools/miri/src/concurrency/init_once.rs

+6-24
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::collections::VecDeque;
22

33
use rustc_index::Idx;
44

5-
use super::sync::EvalContextExtPriv as _;
5+
use super::thread::DynUnblockCallback;
66
use super::vector_clock::VClock;
77
use crate::*;
88

@@ -27,22 +27,6 @@ pub(super) struct InitOnce {
2727

2828
impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
2929
pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
30-
fn init_once_get_or_create_id(
31-
&mut self,
32-
lock: &MPlaceTy<'tcx>,
33-
offset: u64,
34-
) -> InterpResult<'tcx, InitOnceId> {
35-
let this = self.eval_context_mut();
36-
this.get_or_create_id(
37-
lock,
38-
offset,
39-
|ecx| &mut ecx.machine.sync.init_onces,
40-
|_| interp_ok(Default::default()),
41-
)?
42-
.ok_or_else(|| err_ub_format!("init_once has invalid ID"))
43-
.into()
44-
}
45-
4630
#[inline]
4731
fn init_once_status(&mut self, id: InitOnceId) -> InitOnceStatus {
4832
let this = self.eval_context_ref();
@@ -51,11 +35,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
5135

5236
/// Put the thread into the queue waiting for the initialization.
5337
#[inline]
54-
fn init_once_enqueue_and_block(
55-
&mut self,
56-
id: InitOnceId,
57-
callback: impl UnblockCallback<'tcx> + 'tcx,
58-
) {
38+
fn init_once_enqueue_and_block(&mut self, id: InitOnceId, callback: DynUnblockCallback<'tcx>) {
5939
let this = self.eval_context_mut();
6040
let thread = this.active_thread();
6141
let init_once = &mut this.machine.sync.init_onces[id];
@@ -93,7 +73,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
9373

9474
// Each complete happens-before the end of the wait
9575
if let Some(data_race) = &this.machine.data_race {
96-
init_once.clock.clone_from(&data_race.release_clock(&this.machine.threads));
76+
data_race
77+
.release_clock(&this.machine.threads, |clock| init_once.clock.clone_from(clock));
9778
}
9879

9980
// Wake up everyone.
@@ -119,7 +100,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
119100

120101
// Each complete happens-before the end of the wait
121102
if let Some(data_race) = &this.machine.data_race {
122-
init_once.clock.clone_from(&data_race.release_clock(&this.machine.threads));
103+
data_race
104+
.release_clock(&this.machine.threads, |clock| init_once.clock.clone_from(clock));
123105
}
124106

125107
// Wake up one waiting thread, so they can go ahead and try to init this.

0 commit comments

Comments
 (0)