Skip to content

Commit 72acacf

Browse files
authored
Rollup merge of #131286 - RalfJung:miri-sync, r=RalfJung
Miri subtree update r? `@ghost`
2 parents 1bd61bb + 3b418b1 commit 72acacf

40 files changed

Lines changed: 1293 additions & 402 deletions

‎src/tools/miri/cargo-miri/src/phases.rs‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,6 @@ pub fn phase_runner(mut binary_args: impl Iterator<Item = String>, phase: Runner
668668
RunnerPhase::Rustdoc => {
669669
cmd.stdin(std::process::Stdio::piped());
670670
// the warning is wrong, we have a `wait` inside the `scope` closure.
671-
#[expect(clippy::zombie_processes)]
672671
letmut child = cmd.spawn().expect("failed to spawn process");
673672
let child_stdin = child.stdin.take().unwrap();
674673
// Write stdin in a background thread, as it may block.

‎src/tools/miri/rust-version‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
76ed7a1fa40c3f54d3fd3f834e12bf9c932d0146
1+
7067e4aee45c18cfa1c6af3bf79bd097684fb294

‎src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -859,14 +859,15 @@ impl Tree {
859859
) -> Option<UniIndex>{
860860
let node = self.nodes.get(idx).unwrap();
861861

862+
let[child_idx] = node.children[..]else{returnNone};
863+
862864
// We never want to replace the root node, as it is also kept in `root_ptr_tags`.
863-
ifnode.children.len() != 1 || live.contains(&node.tag) || node.parent.is_none(){
865+
if live.contains(&node.tag) || node.parent.is_none(){
864866
returnNone;
865867
}
866868
// Since protected nodes are never GC'd (see `borrow_tracker::FrameExtra::visit_provenance`),
867869
// we know that `node` is not protected because otherwise `live` would
868870
// have contained `node.tag`.
869-
let child_idx = node.children[0];
870871
let child = self.nodes.get(child_idx).unwrap();
871872
// Check that for that one child, `can_be_replaced_by_child` holds for the permission
872873
// on all locations.

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
3939
|ecx| &mut ecx.machine.sync.init_onces,
4040
|_| interp_ok(Default::default()),
4141
)?
42-
.ok_or_else(|| err_ub_format!("init_once has invalid ID")).into()
42+
.ok_or_else(|| err_ub_format!("init_once has invalid ID"))
43+
.into()
4344
}
4445

4546
#[inline]

‎src/tools/miri/src/concurrency/sync.rs‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
307307
|ecx| &mut ecx.machine.sync.mutexes,
308308
|ecx| initialize_data(ecx).map(|data| Mutex{ data, ..Default::default()}),
309309
)?
310-
.ok_or_else(|| err_ub_format!("mutex has invalid ID")).into()
310+
.ok_or_else(|| err_ub_format!("mutex has invalid ID"))
311+
.into()
311312
}
312313

313314
/// Retrieve the additional data stored for a mutex.
@@ -334,7 +335,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
334335
|ecx| &mut ecx.machine.sync.rwlocks,
335336
|ecx| initialize_data(ecx).map(|data| RwLock{ data, ..Default::default()}),
336337
)?
337-
.ok_or_else(|| err_ub_format!("rwlock has invalid ID")).into()
338+
.ok_or_else(|| err_ub_format!("rwlock has invalid ID"))
339+
.into()
338340
}
339341

340342
/// Retrieve the additional data stored for a rwlock.
@@ -375,7 +377,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
375377
|ecx| &mut ecx.machine.sync.condvars,
376378
|ecx| initialize_data(ecx).map(|data| Condvar{ data, ..Default::default()}),
377379
)?
378-
.ok_or_else(|| err_ub_format!("condvar has invalid ID")).into()
380+
.ok_or_else(|| err_ub_format!("condvar has invalid ID"))
381+
.into()
379382
}
380383

381384
/// Retrieve the additional data stored for a condvar.

‎src/tools/miri/src/concurrency/vector_clock.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ impl VClock {
151151
/// Load the internal timestamp slice in the vector clock
152152
#[inline]
153153
pub(super)fnas_slice(&self) -> &[VTimestamp]{
154-
debug_assert!(!self.0.last().is_some_and(|t| t.time()== 0));
154+
debug_assert!(self.0.last().is_none_or(|t| t.time()!= 0));
155155
self.0.as_slice()
156156
}
157157

‎src/tools/miri/src/helpers.rs‎

Lines changed: 13 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -31,65 +31,6 @@ pub enum AccessKind {
3131
Write,
3232
}
3333

34-
// This mapping should match `decode_error_kind` in
35-
// <https://github.com/rust-lang/rust/blob/master/library/std/src/sys/pal/unix/mod.rs>.
36-
constUNIX_IO_ERROR_TABLE:&[(&str, std::io::ErrorKind)] = {
37-
use std::io::ErrorKind::*;
38-
&[
39-
("E2BIG",ArgumentListTooLong),
40-
("EADDRINUSE",AddrInUse),
41-
("EADDRNOTAVAIL",AddrNotAvailable),
42-
("EBUSY",ResourceBusy),
43-
("ECONNABORTED",ConnectionAborted),
44-
("ECONNREFUSED",ConnectionRefused),
45-
("ECONNRESET",ConnectionReset),
46-
("EDEADLK",Deadlock),
47-
("EDQUOT",FilesystemQuotaExceeded),
48-
("EEXIST",AlreadyExists),
49-
("EFBIG",FileTooLarge),
50-
("EHOSTUNREACH",HostUnreachable),
51-
("EINTR",Interrupted),
52-
("EINVAL",InvalidInput),
53-
("EISDIR",IsADirectory),
54-
("ELOOP",FilesystemLoop),
55-
("ENOENT",NotFound),
56-
("ENOMEM",OutOfMemory),
57-
("ENOSPC",StorageFull),
58-
("ENOSYS",Unsupported),
59-
("EMLINK",TooManyLinks),
60-
("ENAMETOOLONG",InvalidFilename),
61-
("ENETDOWN",NetworkDown),
62-
("ENETUNREACH",NetworkUnreachable),
63-
("ENOTCONN",NotConnected),
64-
("ENOTDIR",NotADirectory),
65-
("ENOTEMPTY",DirectoryNotEmpty),
66-
("EPIPE",BrokenPipe),
67-
("EROFS",ReadOnlyFilesystem),
68-
("ESPIPE",NotSeekable),
69-
("ESTALE",StaleNetworkFileHandle),
70-
("ETIMEDOUT",TimedOut),
71-
("ETXTBSY",ExecutableFileBusy),
72-
("EXDEV",CrossesDevices),
73-
// The following have two valid options. We have both for the forwards mapping; only the
74-
// first one will be used for the backwards mapping.
75-
("EPERM",PermissionDenied),
76-
("EACCES",PermissionDenied),
77-
("EWOULDBLOCK",WouldBlock),
78-
("EAGAIN",WouldBlock),
79-
]
80-
};
81-
// This mapping should match `decode_error_kind` in
82-
// <https://github.com/rust-lang/rust/blob/master/library/std/src/sys/pal/windows/mod.rs>.
83-
constWINDOWS_IO_ERROR_TABLE:&[(&str, std::io::ErrorKind)] = {
84-
use std::io::ErrorKind::*;
85-
// FIXME: this is still incomplete.
86-
&[
87-
("ERROR_ACCESS_DENIED",PermissionDenied),
88-
("ERROR_FILE_NOT_FOUND",NotFound),
89-
("ERROR_INVALID_PARAMETER",InvalidInput),
90-
]
91-
};
92-
9334
/// Gets an instance for a path.
9435
///
9536
/// A `None` namespace indicates we are looking for a module.
@@ -745,119 +686,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
745686
self.eval_context_ref().tcx.sess.target.families.iter().any(|f| f == "unix")
746687
}
747688

748-
/// Get last error variable as a place, lazily allocating thread-local storage for it if
749-
/// necessary.
750-
fnlast_error_place(&mutself) -> InterpResult<'tcx,MPlaceTy<'tcx>>{
751-
let this = self.eval_context_mut();
752-
ifletSome(errno_place) = this.active_thread_ref().last_error.as_ref(){
753-
interp_ok(errno_place.clone())
754-
}else{
755-
// Allocate new place, set initial value to 0.
756-
let errno_layout = this.machine.layouts.u32;
757-
let errno_place = this.allocate(errno_layout,MiriMemoryKind::Machine.into())?;
758-
this.write_scalar(Scalar::from_u32(0),&errno_place)?;
759-
this.active_thread_mut().last_error = Some(errno_place.clone());
760-
interp_ok(errno_place)
761-
}
762-
}
763-
764-
/// Sets the last error variable.
765-
fnset_last_error(&mutself,scalar:Scalar) -> InterpResult<'tcx>{
766-
let this = self.eval_context_mut();
767-
let errno_place = this.last_error_place()?;
768-
this.write_scalar(scalar,&errno_place)
769-
}
770-
771-
/// Gets the last error variable.
772-
fnget_last_error(&mutself) -> InterpResult<'tcx,Scalar>{
773-
let this = self.eval_context_mut();
774-
let errno_place = this.last_error_place()?;
775-
this.read_scalar(&errno_place)
776-
}
777-
778-
/// This function tries to produce the most similar OS error from the `std::io::ErrorKind`
779-
/// as a platform-specific errnum.
780-
fnio_error_to_errnum(&self,err: std::io::Error) -> InterpResult<'tcx,Scalar>{
781-
let this = self.eval_context_ref();
782-
let target = &this.tcx.sess.target;
783-
if target.families.iter().any(|f| f == "unix"){
784-
for&(name, kind)inUNIX_IO_ERROR_TABLE{
785-
if err.kind() == kind {
786-
returninterp_ok(this.eval_libc(name));
787-
}
788-
}
789-
throw_unsup_format!("unsupported io error: {err}")
790-
}elseif target.families.iter().any(|f| f == "windows"){
791-
for&(name, kind)inWINDOWS_IO_ERROR_TABLE{
792-
if err.kind() == kind {
793-
returninterp_ok(this.eval_windows("c", name));
794-
}
795-
}
796-
throw_unsup_format!("unsupported io error: {err}");
797-
}else{
798-
throw_unsup_format!(
799-
"converting io::Error into errnum is unsupported for OS {}",
800-
target.os
801-
)
802-
}
803-
}
804-
805-
/// The inverse of `io_error_to_errnum`.
806-
#[allow(clippy::needless_return)]
807-
fntry_errnum_to_io_error(
808-
&self,
809-
errnum:Scalar,
810-
) -> InterpResult<'tcx,Option<std::io::ErrorKind>>{
811-
let this = self.eval_context_ref();
812-
let target = &this.tcx.sess.target;
813-
if target.families.iter().any(|f| f == "unix"){
814-
let errnum = errnum.to_i32()?;
815-
for&(name, kind)inUNIX_IO_ERROR_TABLE{
816-
if errnum == this.eval_libc_i32(name){
817-
returninterp_ok(Some(kind));
818-
}
819-
}
820-
returninterp_ok(None);
821-
}elseif target.families.iter().any(|f| f == "windows"){
822-
let errnum = errnum.to_u32()?;
823-
for&(name, kind)inWINDOWS_IO_ERROR_TABLE{
824-
if errnum == this.eval_windows("c", name).to_u32()? {
825-
returninterp_ok(Some(kind));
826-
}
827-
}
828-
returninterp_ok(None);
829-
}else{
830-
throw_unsup_format!(
831-
"converting errnum into io::Error is unsupported for OS {}",
832-
target.os
833-
)
834-
}
835-
}
836-
837-
/// Sets the last OS error using a `std::io::ErrorKind`.
838-
fnset_last_error_from_io_error(&mutself,err: std::io::Error) -> InterpResult<'tcx>{
839-
self.set_last_error(self.io_error_to_errnum(err)?)
840-
}
841-
842-
/// Helper function that consumes a `std::io::Result<T>` and returns a
843-
/// `InterpResult<'tcx, T>` instead. In case the result is an error, this function returns
844-
/// `Ok(-1)` and sets the last OS error accordingly.
845-
///
846-
/// This function uses `T: From<i32>` instead of `i32` directly because some IO related
847-
/// functions return different integer types (like `read`, that returns an `i64`).
848-
fntry_unwrap_io_result<T:From<i32>>(
849-
&mutself,
850-
result: std::io::Result<T>,
851-
) -> InterpResult<'tcx,T>{
852-
match result {
853-
Ok(ok) => interp_ok(ok),
854-
Err(e) => {
855-
self.eval_context_mut().set_last_error_from_io_error(e)?;
856-
interp_ok((-1).into())
857-
}
858-
}
859-
}
860-
861689
/// Dereference a pointer operand to a place using `layout` instead of the pointer's declared type
862690
fnderef_pointer_as(
863691
&self,
@@ -924,17 +752,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
924752
let nanoseconds_scalar = this.read_scalar(&nanoseconds_place)?;
925753
let nanoseconds = nanoseconds_scalar.to_target_isize(this)?;
926754

927-
interp_ok(try {
928-
// tv_sec must be non-negative.
929-
let seconds:u64 = seconds.try_into().ok()?;
930-
// tv_nsec must be non-negative.
931-
let nanoseconds:u32 = nanoseconds.try_into().ok()?;
932-
if nanoseconds >= 1_000_000_000{
933-
// tv_nsec must not be greater than 999,999,999.
934-
None?
935-
}
936-
Duration::new(seconds, nanoseconds)
937-
})
755+
interp_ok(
756+
try {
757+
// tv_sec must be non-negative.
758+
let seconds:u64 = seconds.try_into().ok()?;
759+
// tv_nsec must be non-negative.
760+
let nanoseconds:u32 = nanoseconds.try_into().ok()?;
761+
if nanoseconds >= 1_000_000_000{
762+
// tv_nsec must not be greater than 999,999,999.
763+
None?
764+
}
765+
Duration::new(seconds, nanoseconds)
766+
},
767+
)
938768
}
939769

940770
/// Read bytes from a byte slice.

‎src/tools/miri/src/lib.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ pub use crate::range_map::RangeMap;
150150
pubusecrate::shims::EmulateItemResult;
151151
pubusecrate::shims::env::{EnvVars,EvalContextExtas _};
152152
pubusecrate::shims::foreign_items::{DynSym,EvalContextExtas _};
153+
pubusecrate::shims::io_error::{EvalContextExtas _,LibcError};
153154
pubusecrate::shims::os_str::EvalContextExtas _;
154155
pubusecrate::shims::panic::{CatchUnwindData,EvalContextExtas _};
155156
pubusecrate::shims::time::EvalContextExtas _;

0 commit comments

Comments
 (0)