From a5f012576cf0dab7439050696f1c0b7795b3f3aa Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 22 Aug 2026 14:53:14 +0200 Subject: [PATCH 01/54] test `f16::mul_add` not double-rounding the result A naive `f32::mul_add(a as f32, b as f32, c as f32) as f16` has insufficient precision --- compiler/rustc_codegen_gcc/src/intrinsic/mod.rs | 2 -- library/coretests/tests/num/floats.rs | 8 ++++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 09ad3254e5714..b3b1bea68e0b4 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -171,7 +171,6 @@ fn f16_builtin<'gcc, 'tcx>( sym::exp2f16 => "exp2f", sym::fabs => "fabsf", sym::floorf16 => "__builtin_floorf", - sym::fmaf16 => "fmaf", sym::logf16 => "logf", sym::log2f16 => "log2f", sym::log10f16 => "log10f", @@ -249,7 +248,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc | sym::expf16 | sym::exp2f16 | sym::floorf16 - | sym::fmaf16 | sym::logf16 | sym::log2f16 | sym::log10f16 diff --git a/library/coretests/tests/num/floats.rs b/library/coretests/tests/num/floats.rs index cc1d1a0b673dc..8c3bc2f61b4fe 100644 --- a/library/coretests/tests/num/floats.rs +++ b/library/coretests/tests/num/floats.rs @@ -58,6 +58,9 @@ pub(crate) trait TestableFloat: Sized { const RAW_MINUS_14_DOT_25: Self; /// The result of 12.3.mul_add(4.5, 6.7) const MUL_ADD_RESULT: Self; + /// The result of 48.34375.mul_add(0.000013887882, 0.12438965), which checks that f16::mul_add + /// is correctly rounded. A naive implementation via f32::mul_add has insufficient precision. + const F16_NO_DOUBLE_ROUNDING_MUL_ADD_RESULT: Self; /// The result of (-12.3).mul_add(-4.5, -6.7) const NEG_MUL_ADD_RESULT: Self; /// Reciprocal of the maximum val @@ -109,6 +112,7 @@ impl TestableFloat for f16 { const RAW_1337: Self = Self::from_bits(0x6539); const RAW_MINUS_14_DOT_25: Self = Self::from_bits(0xcb20); const MUL_ADD_RESULT: Self = 62.031; + const F16_NO_DOUBLE_ROUNDING_MUL_ADD_RESULT: Self = 0.1251; const NEG_MUL_ADD_RESULT: Self = 48.625; const MAX_RECIP: Self = 1.526624e-5; const ASINH_ACOSH_MAX: Self = 11.781; @@ -168,6 +172,7 @@ impl TestableFloat for f32 { const RAW_1337: Self = Self::from_bits(0x44a72000); const RAW_MINUS_14_DOT_25: Self = Self::from_bits(0xc1640000); const MUL_ADD_RESULT: Self = 62.05; + const F16_NO_DOUBLE_ROUNDING_MUL_ADD_RESULT: Self = 0.12506104; const NEG_MUL_ADD_RESULT: Self = 48.65; const MAX_RECIP: Self = 2.938736e-39; const ASINH_ACOSH_MAX: Self = 89.4159851; @@ -200,6 +205,7 @@ impl TestableFloat for f64 { const RAW_1337: Self = Self::from_bits(0x4094e40000000000); const RAW_MINUS_14_DOT_25: Self = Self::from_bits(0xc02c800000000000); const MUL_ADD_RESULT: Self = 62.050000000000004; + const F16_NO_DOUBLE_ROUNDING_MUL_ADD_RESULT: Self = 0.1250610422954375; const NEG_MUL_ADD_RESULT: Self = 48.650000000000006; const MAX_RECIP: Self = 5.562684646268003e-309; const ASINH_ACOSH_MAX: Self = 710.47586007394398; @@ -242,6 +248,7 @@ impl TestableFloat for f128 { const RAW_1337: Self = Self::from_bits(0x40094e40000000000000000000000000); const RAW_MINUS_14_DOT_25: Self = Self::from_bits(0xc002c800000000000000000000000000); const MUL_ADD_RESULT: Self = 62.0500000000000000000000000000000037; + const F16_NO_DOUBLE_ROUNDING_MUL_ADD_RESULT: Self = 0.1250610422954375; const NEG_MUL_ADD_RESULT: Self = 48.6500000000000000000000000000000049; const MAX_RECIP: Self = 8.40525785778023376565669454330438228902076605e-4933; const ASINH_ACOSH_MAX: Self = 11357.216553474703894801348310092223; @@ -1978,6 +1985,7 @@ float_test! { let inf: Float = Float::INFINITY; let neg_inf: Float = Float::NEG_INFINITY; assert_biteq!(flt(12.3).mul_add(flt(4.5), flt(6.7)), Float::MUL_ADD_RESULT); + assert_biteq!(flt( 48.34375).mul_add(flt(0.000013887882), flt(0.12438965)), Float::F16_NO_DOUBLE_ROUNDING_MUL_ADD_RESULT); assert_biteq!((flt(-12.3)).mul_add(flt(-4.5), flt(-6.7)), Float::NEG_MUL_ADD_RESULT); assert_biteq!(flt(0.0).mul_add(8.9, 1.2), 1.2); assert_biteq!(flt(3.4).mul_add(-0.0, 5.6), 5.6); From 2c1542c11659ed05b13f81e84fa0a490026eb4a2 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 23 Aug 2026 12:54:24 +0200 Subject: [PATCH 02/54] proper signature checks for Rust allocator shims --- src/tools/miri/src/shims/alloc.rs | 26 ++++++++++++++----- src/tools/miri/tests/fail/alloc/too_large.rs | 5 ++-- .../miri/tests/fail/alloc/too_large.stderr | 4 +-- .../fail/alloc/unsupported_big_alignment.rs | 5 ++-- .../alloc/unsupported_big_alignment.stderr | 4 +-- .../unsupported_non_power_two_alignment.rs | 8 +++--- ...unsupported_non_power_two_alignment.stderr | 4 +-- .../fail/data_race/dealloc_read_race1.rs | 5 ++-- .../fail/data_race/dealloc_read_race1.stderr | 2 +- .../fail/data_race/dealloc_read_race2.rs | 5 ++-- .../fail/data_race/dealloc_read_race2.stderr | 2 +- .../fail/data_race/dealloc_write_race1.rs | 5 ++-- .../fail/data_race/dealloc_write_race1.stderr | 2 +- .../fail/data_race/dealloc_write_race2.rs | 5 ++-- .../fail/data_race/dealloc_write_race2.stderr | 2 +- 15 files changed, 50 insertions(+), 34 deletions(-) diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs index 3874c00187fdc..fe0a351d635ba 100644 --- a/src/tools/miri/src/shims/alloc.rs +++ b/src/tools/miri/src/shims/alloc.rs @@ -1,4 +1,4 @@ -use rustc_abi::{Align, AlignFromBytesError, CanonAbi, Size}; +use rustc_abi::{Align, AlignFromBytesError, Size}; use rustc_ast::expand::allocator::SpecialAllocatorMethod; use rustc_middle::ty::Ty; use rustc_span::Symbol; @@ -123,8 +123,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match method { SpecialAllocatorMethod::Alloc | SpecialAllocatorMethod::AllocZeroed => { - let [size, align] = - this.check_shim_sig_deprecated(abi, CanonAbi::Rust, link_name, args)?; + let [size, align] = this.check_shim_sig( + shim_sig_nounwind!(extern "Rust" fn(usize, core::mem::Alignment) -> *_), + link_name, + abi, + args, + )?; let size = this.read_target_usize(size)?; let align = this.read_target_usize(align)?; @@ -144,8 +148,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_pointer(ptr, dest) } SpecialAllocatorMethod::Dealloc => { - let [ptr, old_size, align] = - this.check_shim_sig_deprecated(abi, CanonAbi::Rust, link_name, args)?; + let [ptr, old_size, align] = this.check_shim_sig( + shim_sig_nounwind!(extern "Rust" fn(*_, usize, core::mem::Alignment) -> ()), + link_name, + abi, + args, + )?; let ptr = this.read_pointer(ptr)?; let old_size = this.read_target_usize(old_size)?; let align = this.read_target_usize(align)?; @@ -158,8 +166,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) } SpecialAllocatorMethod::Realloc => { - let [ptr, old_size, align, new_size] = - this.check_shim_sig_deprecated(abi, CanonAbi::Rust, link_name, args)?; + let [ptr, old_size, align, new_size] = this.check_shim_sig( + shim_sig_nounwind!(extern "Rust" fn(*_, usize, core::mem::Alignment, usize) -> *_), + link_name, + abi, + args, + )?; let ptr = this.read_pointer(ptr)?; let old_size = this.read_target_usize(old_size)?; let align = this.read_target_usize(align)?; diff --git a/src/tools/miri/tests/fail/alloc/too_large.rs b/src/tools/miri/tests/fail/alloc/too_large.rs index c53318855aba0..899fc30d9a576 100644 --- a/src/tools/miri/tests/fail/alloc/too_large.rs +++ b/src/tools/miri/tests/fail/alloc/too_large.rs @@ -1,13 +1,14 @@ #![feature(rustc_attrs)] +#![feature(ptr_alignment_type)] extern "Rust" { #[rustc_std_internal_symbol] - fn __rust_alloc(size: usize, align: usize) -> *mut u8; + fn __rust_alloc(size: usize, align: core::mem::Alignment) -> *mut u8; } fn main() { let bytes = isize::MAX as usize + 1; unsafe { - __rust_alloc(bytes, 1); //~ERROR: larger than half the address space + __rust_alloc(bytes, 1usize.try_into().unwrap()); //~ERROR: larger than half the address space } } diff --git a/src/tools/miri/tests/fail/alloc/too_large.stderr b/src/tools/miri/tests/fail/alloc/too_large.stderr index 14fad06fc06d2..86c8aac242ac6 100644 --- a/src/tools/miri/tests/fail/alloc/too_large.stderr +++ b/src/tools/miri/tests/fail/alloc/too_large.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: creating an allocation larger than half the address space --> tests/fail/alloc/too_large.rs:LL:CC | -LL | __rust_alloc(bytes, 1); - | ^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here +LL | __rust_alloc(bytes, 1usize.try_into().unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.rs b/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.rs index 34c6a6ce55012..a60156982caa4 100644 --- a/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.rs +++ b/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.rs @@ -3,15 +3,16 @@ // https://github.com/rust-lang/miri/issues/3687 #![feature(rustc_attrs)] +#![feature(ptr_alignment_type)] extern "Rust" { #[rustc_std_internal_symbol] - fn __rust_alloc(size: usize, align: usize) -> *mut u8; + fn __rust_alloc(size: usize, align: core::mem::Alignment) -> *mut u8; } fn main() { unsafe { - __rust_alloc(1, 1 << 30); + __rust_alloc(1, (1 << 30).try_into().unwrap()); //~^ERROR: exceeding rustc's maximum supported value } } diff --git a/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.stderr b/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.stderr index 11d2a855ef715..72ede2682261c 100644 --- a/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.stderr +++ b/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.stderr @@ -1,8 +1,8 @@ error: unsupported operation: creating allocation with alignment ALIGN exceeding rustc's maximum supported value --> tests/fail/alloc/unsupported_big_alignment.rs:LL:CC | -LL | __rust_alloc(1, 1 << 30); - | ^^^^^^^^^^^^^^^^^^^^^^^^ unsupported operation occurred here +LL | __rust_alloc(1, (1 << 30).try_into().unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsupported operation occurred here | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support diff --git a/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.rs b/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.rs index ce8861937f873..4929303b53c86 100644 --- a/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.rs +++ b/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.rs @@ -2,14 +2,12 @@ #![feature(rustc_attrs)] -extern "Rust" { - #[rustc_std_internal_symbol] - fn __rust_alloc(size: usize, align: usize) -> *mut u8; -} +#[path = "../../utils/mod.no_std.rs"] +mod utils; fn main() { unsafe { - __rust_alloc(1, 3); + utils::miri_alloc(1, 3); //~^ERROR: creating allocation with non-power-of-two alignment } } diff --git a/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.stderr b/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.stderr index 827d498e7ec9f..f6e2622bde485 100644 --- a/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.stderr +++ b/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: creating allocation with non-power-of-two alignment ALIGN --> tests/fail/alloc/unsupported_non_power_two_alignment.rs:LL:CC | -LL | __rust_alloc(1, 3); - | ^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here +LL | utils::miri_alloc(1, 3); + | ^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs b/src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs index 64bababe0c853..0b16d0616ba95 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs +++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs @@ -2,6 +2,7 @@ //@compile-flags: -Zmiri-deterministic-concurrency -Zmiri-disable-stacked-borrows #![feature(rustc_attrs)] +#![feature(ptr_alignment_type)] use std::thread::spawn; @@ -13,7 +14,7 @@ unsafe impl Sync for EvilSend {} extern "Rust" { #[rustc_std_internal_symbol] - fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize); + fn __rust_dealloc(ptr: *mut u8, size: usize, align: core::mem::Alignment); } fn main() { @@ -33,7 +34,7 @@ fn main() { //~^ ERROR: Data race detected between (1) non-atomic read on thread `unnamed-1` and (2) deallocation on thread `unnamed-2` ptr.0 as *mut _, std::mem::size_of::(), - std::mem::align_of::(), + std::mem::align_of::().try_into().unwrap(), ); }); diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race1.stderr b/src/tools/miri/tests/fail/data_race/dealloc_read_race1.stderr index feb35ddcd34cf..a9353baa1beaa 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_read_race1.stderr +++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race1.stderr @@ -5,7 +5,7 @@ LL | / ... __rust_dealloc( LL | | ... LL | | ... ptr.0 as *mut _, LL | | ... std::mem::size_of::(), -LL | | ... std::mem::align_of::(), +LL | | ... std::mem::align_of::().try_into().unwrap(), LL | | ... ); | |_______^ (2) just happened here | diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs b/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs index 6e85bcf03aa50..566c729c912bc 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs +++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs @@ -2,6 +2,7 @@ //@compile-flags: -Zmiri-deterministic-concurrency -Zmiri-disable-stacked-borrows #![feature(rustc_attrs)] +#![feature(ptr_alignment_type)] use std::thread::spawn; @@ -13,7 +14,7 @@ unsafe impl Sync for EvilSend {} extern "Rust" { #[rustc_std_internal_symbol] - fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize); + fn __rust_dealloc(ptr: *mut u8, size: usize, align: core::mem::Alignment); } fn main() { @@ -27,7 +28,7 @@ fn main() { __rust_dealloc( ptr.0 as *mut _, std::mem::size_of::(), - std::mem::align_of::(), + std::mem::align_of::().try_into().unwrap(), ) }); diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race2.stderr b/src/tools/miri/tests/fail/data_race/dealloc_read_race2.stderr index f1bd657cc5a84..2452a5587da6a 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_read_race2.stderr +++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race2.stderr @@ -17,7 +17,7 @@ help: ALLOC was deallocated here: LL | / __rust_dealloc( LL | | ptr.0 as *mut _, LL | | std::mem::size_of::(), -LL | | std::mem::align_of::(), +LL | | std::mem::align_of::().try_into().unwrap(), LL | | ) | |_____________^ = note: this is on thread `unnamed-ID` diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs b/src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs index fd71ef09b1253..7fa769e88583f 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs +++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs @@ -2,6 +2,7 @@ //@compile-flags: -Zmiri-deterministic-concurrency -Zmiri-disable-stacked-borrows #![feature(rustc_attrs)] +#![feature(ptr_alignment_type)] use std::thread::spawn; @@ -13,7 +14,7 @@ unsafe impl Sync for EvilSend {} extern "Rust" { #[rustc_std_internal_symbol] - fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize); + fn __rust_dealloc(ptr: *mut u8, size: usize, align: core::mem::Alignment); } fn main() { // Shared atomic pointer @@ -32,7 +33,7 @@ fn main() { //~^ ERROR: Data race detected between (1) non-atomic write on thread `unnamed-1` and (2) deallocation on thread `unnamed-2` ptr.0 as *mut _, std::mem::size_of::(), - std::mem::align_of::(), + std::mem::align_of::().try_into().unwrap(), ); }); diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race1.stderr b/src/tools/miri/tests/fail/data_race/dealloc_write_race1.stderr index f24830d73fb1e..3dbc3f3851391 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_write_race1.stderr +++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race1.stderr @@ -5,7 +5,7 @@ LL | / ... __rust_dealloc( LL | | ... LL | | ... ptr.0 as *mut _, LL | | ... std::mem::size_of::(), -LL | | ... std::mem::align_of::(), +LL | | ... std::mem::align_of::().try_into().unwrap(), LL | | ... ); | |_______^ (2) just happened here | diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs b/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs index 5c8bbc14a4927..da452b00244bf 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs +++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs @@ -2,6 +2,7 @@ //@compile-flags: -Zmiri-deterministic-concurrency -Zmiri-disable-stacked-borrows #![feature(rustc_attrs)] +#![feature(ptr_alignment_type)] use std::thread::spawn; @@ -13,7 +14,7 @@ unsafe impl Sync for EvilSend {} extern "Rust" { #[rustc_std_internal_symbol] - fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize); + fn __rust_dealloc(ptr: *mut u8, size: usize, align: core::mem::Alignment); } fn main() { // Shared atomic pointer @@ -26,7 +27,7 @@ fn main() { __rust_dealloc( ptr.0 as *mut _, std::mem::size_of::(), - std::mem::align_of::(), + std::mem::align_of::().try_into().unwrap(), ); }); diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race2.stderr b/src/tools/miri/tests/fail/data_race/dealloc_write_race2.stderr index a4712554a0874..dc0f8a30a0f6b 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_write_race2.stderr +++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race2.stderr @@ -17,7 +17,7 @@ help: ALLOC was deallocated here: LL | / __rust_dealloc( LL | | ptr.0 as *mut _, LL | | std::mem::size_of::(), -LL | | std::mem::align_of::(), +LL | | std::mem::align_of::().try_into().unwrap(), LL | | ); | |_____________^ = note: this is on thread `unnamed-ID` From cd85d93ee9f533f4ecf31d1ef3e9c74900d73b6d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 23 Aug 2026 13:16:10 +0200 Subject: [PATCH 03/54] bump nix --- src/tools/miri/Cargo.lock | 4 ++-- src/tools/miri/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock index d418b15f2a952..dfd839b8ce002 100644 --- a/src/tools/miri/Cargo.lock +++ b/src/tools/miri/Cargo.lock @@ -1061,9 +1061,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.30.1" +version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" dependencies = [ "bitflags", "cfg-if", diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml index e0547a4539612..62dce3df8bf01 100644 --- a/src/tools/miri/Cargo.toml +++ b/src/tools/miri/Cargo.toml @@ -37,7 +37,7 @@ libloading = { version = "0.9", optional = true } serde = { version = "1.0.219", features = ["derive"], optional = true } [target.'cfg(target_os = "linux")'.dependencies] -nix = { version = "0.30.1", features = ["mman", "ptrace", "signal"], optional = true } +nix = { version = "0.31.0", features = ["mman", "ptrace", "signal"], optional = true } ipc-channel = { version = "0.22.0", optional = true } capstone = { version = "0.14", features = ["arch_x86", "full"], default-features = false, optional = true} From 6ddb88e6abcc840b93ec5266898389b55a100de0 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 23 Aug 2026 13:16:23 +0200 Subject: [PATCH 04/54] cargo update --- src/tools/miri/Cargo.lock | 635 ++++++++++----------------- src/tools/miri/Cargo.toml | 5 +- src/tools/miri/cargo-miri/Cargo.lock | 297 ++----------- src/tools/miri/priroda/Cargo.lock | 514 +++++++--------------- src/tools/miri/tests/deps/Cargo.lock | 418 +++--------------- 5 files changed, 514 insertions(+), 1355 deletions(-) diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock index dfd839b8ce002..3775531a3f16d 100644 --- a/src/tools/miri/Cargo.lock +++ b/src/tools/miri/Cargo.lock @@ -19,9 +19,9 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aes" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fc76eaeac4c9164506c466d4ffdd8ec9d0c5bf57ee97177c4d8eceb3a0e138" +checksum = "f8eb277bec05f56a0e0591f155a484cbd0f4f07ff2905051a48c72f004f7ed58" dependencies = [ "cipher", "cpubits", @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" dependencies = [ "memchr", ] @@ -55,15 +55,15 @@ checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "backtrace" @@ -82,32 +82,32 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.11.1" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" [[package]] name = "bstr" -version = "1.12.1" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" +checksum = "6bb31b46c14244e20ee9984b11bf5c992b91fb6939fea616e3512c8baecdbe5f" dependencies = [ "memchr", "regex-automata", - "serde", + "serde_core", ] [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "camino" -version = "1.2.2" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" +checksum = "bb1307f12aa967b5a58416e87b3653360e0fd614a016b6e970db08fecbb1b80d" dependencies = [ "serde_core", ] @@ -133,32 +133,32 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.9" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" +checksum = "122ec45a44b270afd1402f351b782c676b173e3c3fb28d86ff7ebfb4d86a4ee4" dependencies = [ "serde", ] [[package]] name = "cargo_metadata" -version = "0.18.1" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +checksum = "ef987d17b0a113becdd19d3d0022d04d7ef41f9efe4f3fb63ac44ba61df3ade9" dependencies = [ "camino", "cargo-platform", "semver", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.20", ] [[package]] name = "cc" -version = "1.4.3" +version = "1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "509591b7bcd67f4ef775afad7662703b4935daaa6ec0e5605cfb1090b32a2b6d" +checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273" dependencies = [ "find-msvc-tools", "jobserver", @@ -174,15 +174,15 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" [[package]] name = "chacha20" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" +checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" dependencies = [ "cfg-if", "cpufeatures", @@ -191,9 +191,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "num-traits", ] @@ -210,9 +210,9 @@ dependencies = [ [[package]] name = "cipher" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e34d8227fe1ba289043aeb13792056ff80fd6de1a9f49137a5f499de8e8c78ea" +checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c" dependencies = [ "crypto-common", "inout", @@ -220,18 +220,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.6.1" +version = "4.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" +checksum = "473c7e07f409a8d772161724aa8db6a765a2532a70f9667eeb7b49d3d02fbdca" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.6.0" +version = "4.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" +checksum = "7b48fea5a88e9ae728a2dcbedbfc0e730f7d60da42e1cb049a83c9fb8b789889" dependencies = [ "anstyle", "clap_lex", @@ -259,7 +259,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" dependencies = [ - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -317,9 +317,9 @@ checksum = "55b672471b4e9f9e95499ea597ff64941a309b2cdbffcc46f2cc5e2d971fd335" [[package]] name = "console" -version = "0.16.3" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87" +checksum = "4fe5f465a4f6fee88fad41b85d990f84c835335e85b5d9e6e63e0d06d28cba7c" dependencies = [ "encode_unicode", "libc", @@ -344,48 +344,48 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.15" +version = "0.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +checksum = "d85363c37faeca707aef026efa9f3b34d077bce547e48f770770625c6013679e" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" [[package]] name = "crypto-common" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" dependencies = [ "hybrid-array", ] [[package]] name = "cxx" -version = "1.0.194" +version = "1.0.199" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747d8437319e3a2f43d93b341c137927ca70c0f5dabeea7a005a73665e247c7e" +checksum = "824894a4a85dca76d4c95c2b9098c036f5a29f627b30c12780774f6654e60974" dependencies = [ "cc", "cxx-build", "cxxbridge-cmd", "cxxbridge-flags", "cxxbridge-macro", - "foldhash 0.2.0", + "foldhash", "link-cplusplus", ] [[package]] name = "cxx-build" -version = "1.0.194" +version = "1.0.199" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0f4697d190a142477b16aef7da8a99bfdc41e7e8b1687583c0d23a79c7afc1e" +checksum = "f1ae0b651ea5b0000b19513aef5a03f194d7e3486f2d9258b658da8677fe9036" dependencies = [ "cc", "codespan-reporting", @@ -393,39 +393,39 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn", + "syn 3.0.3", ] [[package]] name = "cxxbridge-cmd" -version = "1.0.194" +version = "1.0.199" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0956799fa8678d4c50eed028f2de1c0552ae183c76e976cf7ca8c4e36a7c328" +checksum = "fb05f91d3fb8435d9bab6ac5ce6ac1868be774325fb7fb2a91be39393b21388e" dependencies = [ "clap", "codespan-reporting", "indexmap", "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] name = "cxxbridge-flags" -version = "1.0.194" +version = "1.0.199" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23384a836ab4f0ad98ace7e3955ad2de39de42378ab487dc28d3990392cb283a" +checksum = "bf293202e0e3e98495785745389e8d0755b217e66f19194a5c695c25e03282ef" [[package]] name = "cxxbridge-macro" -version = "1.0.194" +version = "1.0.199" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6acc6b5822b9526adfb4fc377b67128fdd60aac757cc4a741a6278603f763cf" +checksum = "ca001d746947c7249ed9d332a10f7a59daedbafeb0ec68c5c18a7db7a93f6ccc" dependencies = [ "indexmap", "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] @@ -451,13 +451,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] @@ -496,19 +496,20 @@ dependencies = [ [[package]] name = "eyre" -version = "0.6.12" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +checksum = "c08309dbcc659c5549a24ddb9b27027640641b282ef5768267c7e675558986a3" dependencies = [ + "autocfg", "indenter", "once_cell", ] [[package]] name = "fastrand" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" [[package]] name = "find-msvc-tools" @@ -516,12 +517,6 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890" -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - [[package]] name = "foldhash" version = "0.2.0" @@ -539,21 +534,21 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-task" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-util" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-core", "futures-task", @@ -597,16 +592,14 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "libc", "r-efi 6.0.0", "rand_core 0.10.1", - "wasip2", - "wasip3", ] [[package]] @@ -630,41 +623,26 @@ dependencies = [ "url", ] -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "foldhash 0.1.5", -] - [[package]] name = "hashbrown" version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - [[package]] name = "hybrid-array" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" +checksum = "707114b52a152fa7bdb290cd7cd5912d9467273b6d74e21b8d81aca1f8533f6b" dependencies = [ "typenum", ] [[package]] name = "icu_collections" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" dependencies = [ "displaydoc", "potential_utf", @@ -676,9 +654,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" +checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" dependencies = [ "displaydoc", "litemap", @@ -689,9 +667,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -703,16 +681,17 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" +checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" [[package]] name = "icu_properties" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" +checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" dependencies = [ + "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", @@ -723,15 +702,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" +checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" [[package]] name = "icu_provider" -version = "2.2.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" dependencies = [ "displaydoc", "icu_locale_core", @@ -742,12 +721,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - [[package]] name = "idna" version = "1.1.0" @@ -782,16 +755,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.17.1", - "serde", - "serde_core", + "hashbrown", ] [[package]] name = "indicatif" -version = "0.18.4" +version = "0.18.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25470f23803092da7d239834776d653104d551bc4d7eacaf31e6837854b8e9eb" +checksum = "9433806cd6b4ec1aba79c021c7e4c58fb4c3b9977c085062e611ac929998fb0c" dependencies = [ "console", "portable-atomic", @@ -819,11 +790,11 @@ dependencies = [ "libc", "mio", "postcard", - "rand 0.9.4", - "rustc-hash 2.1.2", + "rand 0.9.5", + "rustc-hash 2.1.3", "serde_core", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.20", "uuid", "windows", ] @@ -836,23 +807,22 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jobserver" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.3", "libc", ] [[package]] name = "js-sys" -version = "0.3.98" +version = "0.3.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" +checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a" dependencies = [ "cfg-if", "futures-util", - "once_cell", "wasm-bindgen", ] @@ -862,12 +832,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - [[package]] name = "levenshtein" version = "1.0.5" @@ -876,9 +840,9 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" [[package]] name = "libc" -version = "0.2.186" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "libffi" @@ -901,9 +865,9 @@ dependencies = [ [[package]] name = "libgit2-sys" -version = "0.18.4+1.9.3" +version = "0.18.8+1.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b26f66f35e1871b22efcf7191564123d2a446ca0538cde63c23adfefa9b15b7" +checksum = "7f7c568b25d7489bc3fb2988ed69ab111d2944d2f5fec3d5c987fe545ea97b50" dependencies = [ "cc", "libc", @@ -924,18 +888,18 @@ dependencies = [ [[package]] name = "libredox" -version = "0.1.16" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" +checksum = "28d0a00925a9f930d679b6789b721e3a7f9ed110f41b86d2497caa780c3a070a" dependencies = [ "libc", ] [[package]] name = "libz-sys" -version = "1.1.28" +version = "1.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc3a226e576f50782b3305c5ccf458698f92798987f551c6a02efe8276721e22" +checksum = "85bc9657773828b90eeb625adff10eeac83cc21bbfd8e23a03eaa8a33c9e28d9" dependencies = [ "cc", "libc", @@ -960,9 +924,9 @@ checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" +checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" [[package]] name = "lock_api" @@ -975,9 +939,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" [[package]] name = "measureme" @@ -995,9 +959,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "memmap2" @@ -1019,9 +983,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.0" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" dependencies = [ "libc", "log", @@ -1041,15 +1005,16 @@ dependencies = [ "colored", "directories", "genmc-sys", - "getrandom 0.4.2", + "getrandom 0.4.3", "ipc-channel", "libc", "libffi", + "libffi-sys", "libloading", "measureme", "mio", "nix", - "rand 0.10.1", + "rand 0.10.2", "regex", "rustc_version", "serde", @@ -1103,9 +1068,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.115" +version = "0.9.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "158fe5b292746440aa6e7a7e690e55aeb72d41505e2804c23c6973ad0e9c9781" +checksum = "b47e7e6bb2c38cd930d25a23b40fa52e068c10e85f3e03a7f5ba5aaca5713695" dependencies = [ "cc", "libc", @@ -1189,15 +1154,15 @@ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkg-config" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" [[package]] name = "portable-atomic" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" [[package]] name = "postcard" @@ -1213,9 +1178,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" dependencies = [ "zerovec", ] @@ -1238,30 +1203,20 @@ dependencies = [ "owo-colors", ] -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn", -] - [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.45" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] @@ -1280,9 +1235,9 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" dependencies = [ "rand_chacha", "rand_core 0.9.5", @@ -1290,12 +1245,12 @@ dependencies = [ [[package]] name = "rand" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" dependencies = [ "chacha20", - "getrandom 0.4.2", + "getrandom 0.4.3", "rand_core 0.10.1", ] @@ -1341,14 +1296,14 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.17", "libredox", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] name = "regex" -version = "1.12.3" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", @@ -1358,9 +1313,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" dependencies = [ "aho-corasick", "memchr", @@ -1369,15 +1324,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "rustc-demangle" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" +checksum = "b74b56ffa8bb2830709a538c2cbcae9aa062db0d2a42563bfb09bdaae44020eb" [[package]] name = "rustc-hash" @@ -1387,9 +1342,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] name = "rustc_version" @@ -1427,9 +1382,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "scopeguard" @@ -1455,9 +1410,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", "serde_derive", @@ -1465,29 +1420,29 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" dependencies = [ "itoa", "memchr", @@ -1525,9 +1480,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" -version = "1.15.1" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" [[package]] name = "spanned" @@ -1560,9 +1515,20 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.117" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" dependencies = [ "proc-macro2", "quote", @@ -1577,7 +1543,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -1587,7 +1553,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.4.2", + "getrandom 0.4.3", "once_cell", "rustix", "windows-sys", @@ -1613,11 +1579,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" dependencies = [ - "thiserror-impl 2.0.18", + "thiserror-impl 2.0.20", ] [[package]] @@ -1628,34 +1594,34 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] name = "thread_local" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" dependencies = [ "cfg-if", ] [[package]] name = "tinystr" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" +checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" dependencies = [ "displaydoc", "zerovec", @@ -1704,15 +1670,15 @@ dependencies = [ [[package]] name = "typenum" -version = "1.20.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "ui_test" -version = "0.30.5" +version = "0.30.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "980133b75aa9a95dc94feaf629d92d22c1172186f1fa1266b91f5b91414cf9a5" +checksum = "8c8811281d587a786747c0c49245925016c07767bc996305bdd34d5ce076786a" dependencies = [ "annotate-snippets", "anyhow", @@ -1746,12 +1712,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "unit-prefix" version = "0.5.2" @@ -1778,11 +1738,11 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.23.1" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" +checksum = "f053576934f05a761a402421fbbe3d425d9366f75f978806a037b3ca481abecc" dependencies = [ - "getrandom 0.4.2", + "getrandom 0.4.3", "js-sys", "wasm-bindgen", ] @@ -1807,27 +1767,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.3+wasi-0.2.9" +version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ - "wit-bindgen 0.57.1", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" -dependencies = [ - "wit-bindgen 0.51.0", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.121" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" +checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70" dependencies = [ "cfg-if", "once_cell", @@ -1838,9 +1789,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.121" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" +checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1848,60 +1799,26 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.121" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" +checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn", + "syn 2.0.119", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.121" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" +checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf" dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap", - "wasm-encoder", - "wasmparser", -] - -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags", - "hashbrown 0.15.5", - "indexmap", - "semver", -] - [[package]] name = "web-time" version = "1.1.0" @@ -1975,7 +1892,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -1986,7 +1903,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -2047,111 +1964,23 @@ dependencies = [ "windows-link 0.1.3", ] -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - [[package]] name = "wit-bindgen" version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck", - "indexmap", - "prettyplease", - "syn", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", -] - [[package]] name = "writeable" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" +checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" [[package]] name = "yoke" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -2166,35 +1995,35 @@ checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.48" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.48" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "zerofrom" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] @@ -2207,15 +2036,15 @@ checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", "synstructure", ] [[package]] name = "zerotrie" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" dependencies = [ "displaydoc", "yoke", @@ -2224,9 +2053,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.6" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" dependencies = [ "yoke", "zerofrom", @@ -2235,17 +2064,17 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.3" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] name = "zmij" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml index 62dce3df8bf01..de4687715c06b 100644 --- a/src/tools/miri/Cargo.toml +++ b/src/tools/miri/Cargo.toml @@ -33,6 +33,9 @@ mio = { version = "1.1.1", features = ["os-poll", "net"] } libc = "0.2" # native-lib dependencies libffi = { version = "5.1.0", optional = true } +# libffi-sys is pinned to 4.1.0 due to . +# FIXME: remove this dependency entirely when that is fixed, we only need it indirectly via libffi. +libffi-sys = { version = "=4.1.0", optional = true, default-features = false } libloading = { version = "0.9", optional = true } serde = { version = "1.0.219", features = ["derive"], optional = true } @@ -66,7 +69,7 @@ genmc = ["dep:genmc-sys"] stack-cache = [] expensive-consistency-checks = ["stack-cache"] tracing = ["serde_json"] -native-lib = ["dep:libffi", "dep:libloading", "dep:capstone", "dep:ipc-channel", "dep:nix", "dep:serde"] +native-lib = ["dep:libffi", "dep:libffi-sys", "dep:libloading", "dep:capstone", "dep:ipc-channel", "dep:nix", "dep:serde"] check_only = ["libffi?/check_only", "capstone?/check_only", "genmc-sys?/check_only"] [lints.rust.unexpected_cfgs] diff --git a/src/tools/miri/cargo-miri/Cargo.lock b/src/tools/miri/cargo-miri/Cargo.lock index 288ef8a6eb7f3..5deb41b66ab8e 100644 --- a/src/tools/miri/cargo-miri/Cargo.lock +++ b/src/tools/miri/cargo-miri/Cargo.lock @@ -4,21 +4,21 @@ version = 4 [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] name = "bitflags" -version = "2.11.1" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" [[package]] name = "camino" -version = "1.2.2" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" +checksum = "bb1307f12aa967b5a58416e87b3653360e0fd614a016b6e970db08fecbb1b80d" dependencies = [ "serde_core", ] @@ -105,15 +105,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" - -[[package]] -name = "foldhash" -version = "0.1.5" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" [[package]] name = "getrandom" @@ -128,24 +122,13 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "libc", "r-efi", - "wasip2", - "wasip3", -] - -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "foldhash", ] [[package]] @@ -154,18 +137,6 @@ version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - [[package]] name = "indexmap" version = "2.14.0" @@ -173,9 +144,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.17.1", - "serde", - "serde_core", + "hashbrown", ] [[package]] @@ -184,23 +153,17 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - [[package]] name = "libc" -version = "0.2.186" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "libredox" -version = "0.1.16" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" +checksum = "28d0a00925a9f930d679b6789b721e3a7f9ed110f41b86d2497caa780c3a070a" dependencies = [ "libc", ] @@ -211,17 +174,11 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" -[[package]] -name = "log" -version = "0.4.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" - [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "once_cell" @@ -235,30 +192,20 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn", -] - [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.45" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] @@ -342,9 +289,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", "serde_derive", @@ -352,18 +299,18 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", @@ -372,9 +319,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" dependencies = [ "itoa", "memchr", @@ -394,9 +341,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.117" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" dependencies = [ "proc-macro2", "quote", @@ -410,7 +357,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.4.2", + "getrandom 0.4.3", "once_cell", "rustix", "windows-sys", @@ -418,18 +365,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", @@ -438,9 +385,9 @@ dependencies = [ [[package]] name = "toml" -version = "1.1.2+spec-1.1.0" +version = "1.1.4+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +checksum = "3aace63f4bbcdfc2c965b059de67119c89c4017a70d633be6c104910f67056f5" dependencies = [ "indexmap", "serde_core", @@ -462,18 +409,18 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.1.2+spec-1.1.0" +version = "1.1.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" dependencies = [ "winnow", ] [[package]] name = "toml_writer" -version = "1.1.1+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" +checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" [[package]] name = "unicode-ident" @@ -481,12 +428,6 @@ version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "walkdir" version = "2.5.0" @@ -503,58 +444,6 @@ version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" -[[package]] -name = "wasip2" -version = "1.0.3+wasi-0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" -dependencies = [ - "wit-bindgen 0.57.1", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" -dependencies = [ - "wit-bindgen 0.51.0", -] - -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap", - "wasm-encoder", - "wasmparser", -] - -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags", - "hashbrown 0.15.5", - "indexmap", - "semver", -] - [[package]] name = "winapi-util" version = "0.1.11" @@ -581,106 +470,12 @@ dependencies = [ [[package]] name = "winnow" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0" - -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - -[[package]] -name = "wit-bindgen" -version = "0.57.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" - -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck", - "indexmap", - "prettyplease", - "syn", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", -] +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" [[package]] name = "zmij" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/src/tools/miri/priroda/Cargo.lock b/src/tools/miri/priroda/Cargo.lock index 48ba54ef8eebf..8d4272630e08a 100644 --- a/src/tools/miri/priroda/Cargo.lock +++ b/src/tools/miri/priroda/Cargo.lock @@ -19,9 +19,9 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aes" -version = "0.9.0" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66bd29a732b644c0431c6140f370d097879203d79b80c94a6747ba0872adaef8" +checksum = "f8eb277bec05f56a0e0591f155a484cbd0f4f07ff2905051a48c72f004f7ed58" dependencies = [ "cipher", "cpubits", @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" dependencies = [ "memchr", ] @@ -55,15 +55,15 @@ checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "backtrace" @@ -82,32 +82,32 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.11.1" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" [[package]] name = "bstr" -version = "1.12.1" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" +checksum = "6bb31b46c14244e20ee9984b11bf5c992b91fb6939fea616e3512c8baecdbe5f" dependencies = [ "memchr", "regex-automata", - "serde", + "serde_core", ] [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "camino" -version = "1.2.2" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" +checksum = "bb1307f12aa967b5a58416e87b3653360e0fd614a016b6e970db08fecbb1b80d" dependencies = [ "serde_core", ] @@ -151,14 +151,14 @@ dependencies = [ "semver", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] name = "cc" -version = "1.2.62" +version = "1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" +checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273" dependencies = [ "find-msvc-tools", "shlex", @@ -172,15 +172,15 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" [[package]] name = "chacha20" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" +checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" dependencies = [ "cfg-if", "cpufeatures", @@ -189,9 +189,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "num-traits", ] @@ -208,9 +208,9 @@ dependencies = [ [[package]] name = "cipher" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e34d8227fe1ba289043aeb13792056ff80fd6de1a9f49137a5f499de8e8c78ea" +checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c" dependencies = [ "crypto-common", "inout", @@ -222,7 +222,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" dependencies = [ - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -269,9 +269,9 @@ checksum = "55b672471b4e9f9e95499ea597ff64941a309b2cdbffcc46f2cc5e2d971fd335" [[package]] name = "console" -version = "0.16.3" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87" +checksum = "4fe5f465a4f6fee88fad41b85d990f84c835335e85b5d9e6e63e0d06d28cba7c" dependencies = [ "encode_unicode", "libc", @@ -296,24 +296,24 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.15" +version = "0.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +checksum = "d85363c37faeca707aef026efa9f3b34d077bce547e48f770770625c6013679e" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" [[package]] name = "crypto-common" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" dependencies = [ "hybrid-array", ] @@ -368,12 +368,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - [[package]] name = "errno" version = "0.3.14" @@ -386,49 +380,44 @@ dependencies = [ [[package]] name = "eyre" -version = "0.6.12" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +checksum = "c08309dbcc659c5549a24ddb9b27027640641b282ef5768267c7e675558986a3" dependencies = [ + "autocfg", "indenter", "once_cell", ] [[package]] name = "fastrand" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" [[package]] name = "find-msvc-tools" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" - -[[package]] -name = "foldhash" -version = "0.1.5" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890" [[package]] name = "futures-core" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-task" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-util" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-core", "futures-task", @@ -461,16 +450,14 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "libc", "r-efi 6.0.0", "rand_core 0.10.1", - "wasip2", - "wasip3", ] [[package]] @@ -479,65 +466,26 @@ version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "foldhash", -] - -[[package]] -name = "hashbrown" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - [[package]] name = "hybrid-array" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" +checksum = "707114b52a152fa7bdb290cd7cd5912d9467273b6d74e21b8d81aca1f8533f6b" dependencies = [ "typenum", ] -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - [[package]] name = "indenter" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" -[[package]] -name = "indexmap" -version = "2.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" -dependencies = [ - "equivalent", - "hashbrown 0.17.1", - "serde", - "serde_core", -] - [[package]] name = "indicatif" -version = "0.18.4" +version = "0.18.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25470f23803092da7d239834776d653104d551bc4d7eacaf31e6837854b8e9eb" +checksum = "9433806cd6b4ec1aba79c021c7e4c58fb4c3b9977c085062e611ac929998fb0c" dependencies = [ "console", "portable-atomic", @@ -565,11 +513,11 @@ dependencies = [ "libc", "mio", "postcard", - "rand 0.9.4", - "rustc-hash 2.1.2", + "rand 0.9.5", + "rustc-hash 2.1.3", "serde_core", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.20", "uuid", "windows", ] @@ -582,13 +530,12 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "js-sys" -version = "0.3.98" +version = "0.3.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" +checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a" dependencies = [ "cfg-if", "futures-util", - "once_cell", "wasm-bindgen", ] @@ -598,12 +545,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - [[package]] name = "levenshtein" version = "1.0.5" @@ -612,9 +553,9 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" [[package]] name = "libc" -version = "0.2.186" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "libffi" @@ -647,9 +588,9 @@ dependencies = [ [[package]] name = "libredox" -version = "0.1.16" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" +checksum = "28d0a00925a9f930d679b6789b721e3a7f9ed110f41b86d2497caa780c3a070a" dependencies = [ "libc", ] @@ -671,9 +612,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" [[package]] name = "measureme" @@ -691,9 +632,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "memmap2" @@ -715,9 +656,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.0" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" dependencies = [ "libc", "log", @@ -735,24 +676,25 @@ dependencies = [ "chrono", "chrono-tz", "directories", - "getrandom 0.4.2", + "getrandom 0.4.3", "ipc-channel", "libc", "libffi", + "libffi-sys", "libloading", "measureme", "mio", "nix", - "rand 0.10.1", + "rand 0.10.2", "serde", "smallvec", ] [[package]] name = "nix" -version = "0.30.1" +version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" dependencies = [ "bitflags", "cfg-if", @@ -854,9 +796,9 @@ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "portable-atomic" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" [[package]] name = "postcard" @@ -888,16 +830,6 @@ dependencies = [ "owo-colors", ] -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn", -] - [[package]] name = "priroda" version = "0.1.0" @@ -910,18 +842,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.45" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] @@ -940,9 +872,9 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" dependencies = [ "rand_chacha", "rand_core 0.9.5", @@ -950,12 +882,12 @@ dependencies = [ [[package]] name = "rand" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" dependencies = [ "chacha20", - "getrandom 0.4.2", + "getrandom 0.4.3", "rand_core 0.10.1", ] @@ -1001,14 +933,14 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.17", "libredox", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] name = "regex" -version = "1.12.4" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", @@ -1018,9 +950,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" dependencies = [ "aho-corasick", "memchr", @@ -1035,9 +967,9 @@ checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "rustc-demangle" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" +checksum = "b74b56ffa8bb2830709a538c2cbcae9aa062db0d2a42563bfb09bdaae44020eb" [[package]] name = "rustc-hash" @@ -1047,9 +979,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] name = "rustc_version" @@ -1087,9 +1019,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "scopeguard" @@ -1109,9 +1041,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", "serde_derive", @@ -1119,29 +1051,29 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" dependencies = [ "itoa", "memchr", @@ -1161,9 +1093,9 @@ dependencies = [ [[package]] name = "shlex" -version = "1.3.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "siphasher" @@ -1179,9 +1111,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" -version = "1.15.1" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" [[package]] name = "spanned" @@ -1202,9 +1134,20 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "syn" -version = "2.0.117" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" dependencies = [ "proc-macro2", "quote", @@ -1218,7 +1161,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.4.2", + "getrandom 0.4.3", "once_cell", "rustix", "windows-sys", @@ -1235,11 +1178,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" dependencies = [ - "thiserror-impl 2.0.18", + "thiserror-impl 2.0.20", ] [[package]] @@ -1250,25 +1193,25 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] name = "thread_local" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" dependencies = [ "cfg-if", ] @@ -1316,9 +1259,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.20.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "ui_test" @@ -1358,12 +1301,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "unit-prefix" version = "0.5.2" @@ -1372,11 +1309,11 @@ checksum = "81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3" [[package]] name = "uuid" -version = "1.23.1" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" +checksum = "f053576934f05a761a402421fbbe3d425d9366f75f978806a037b3ca481abecc" dependencies = [ - "getrandom 0.4.2", + "getrandom 0.4.3", "js-sys", "wasm-bindgen", ] @@ -1395,27 +1332,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.3+wasi-0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" -dependencies = [ - "wit-bindgen 0.57.1", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ - "wit-bindgen 0.51.0", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.121" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" +checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70" dependencies = [ "cfg-if", "once_cell", @@ -1426,9 +1354,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.121" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" +checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1436,60 +1364,26 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.121" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" +checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn", + "syn 2.0.119", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.121" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" +checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf" dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap", - "wasm-encoder", - "wasmparser", -] - -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags", - "hashbrown 0.15.5", - "indexmap", - "semver", -] - [[package]] name = "web-time" version = "1.1.0" @@ -1554,7 +1448,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -1565,7 +1459,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -1626,122 +1520,34 @@ dependencies = [ "windows-link 0.1.3", ] -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - [[package]] name = "wit-bindgen" version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck", - "indexmap", - "prettyplease", - "syn", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", -] - [[package]] name = "zerocopy" -version = "0.8.48" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.48" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "zmij" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/src/tools/miri/tests/deps/Cargo.lock b/src/tools/miri/tests/deps/Cargo.lock index 7c7112f3af6b7..facfdee075bc4 100644 --- a/src/tools/miri/tests/deps/Cargo.lock +++ b/src/tools/miri/tests/deps/Cargo.lock @@ -2,29 +2,23 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "anyhow" -version = "1.0.102" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" - [[package]] name = "bitflags" -version = "2.11.1" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "bytes" -version = "1.11.1" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] name = "cfg-if" @@ -39,12 +33,6 @@ dependencies = [ "futures", ] -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - [[package]] name = "errno" version = "0.3.14" @@ -57,21 +45,15 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" - -[[package]] -name = "foldhash" -version = "0.1.5" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" [[package]] name = "futures" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3" dependencies = [ "futures-channel", "futures-core", @@ -83,9 +65,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ "futures-core", "futures-sink", @@ -93,44 +75,44 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-io" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" [[package]] name = "futures-macro" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] name = "futures-sink" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" [[package]] name = "futures-task" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-util" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-core", "futures-macro", @@ -178,91 +160,37 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "libc", "r-efi 6.0.0", - "wasip2", - "wasip3", ] -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "foldhash", -] - -[[package]] -name = "hashbrown" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - [[package]] name = "hermit-abi" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - -[[package]] -name = "indexmap" -version = "2.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" -dependencies = [ - "equivalent", - "hashbrown 0.17.1", - "serde", - "serde_core", -] - -[[package]] -name = "itoa" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" - [[package]] name = "js-sys" -version = "0.3.98" +version = "0.3.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" +checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a" dependencies = [ "cfg-if", "futures-util", - "once_cell", "wasm-bindgen", ] -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - [[package]] name = "libc" -version = "0.2.188" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22053b6a34f84abc97f9129e61334f40174659a1b9bd18c970b83db6a9a6348b" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "linux-raw-sys" @@ -270,23 +198,11 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" -[[package]] -name = "log" -version = "0.4.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" - -[[package]] -name = "memchr" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" - [[package]] name = "mio" -version = "1.2.0" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" dependencies = [ "libc", "wasi 0.11.1+wasi-snapshot-preview1", @@ -342,30 +258,20 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn", -] - [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.45" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] @@ -397,57 +303,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "semver" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.149" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" -dependencies = [ - "itoa", - "memchr", - "serde", - "serde_core", - "zmij", -] +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "signal-hook-registry" @@ -467,9 +325,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "socket2" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", "windows-sys", @@ -477,9 +335,20 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.117" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" dependencies = [ "proc-macro2", "quote", @@ -493,7 +362,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.4.2", + "getrandom 0.4.3", "once_cell", "rustix", "windows-sys", @@ -501,9 +370,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.52.3" +version = "1.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" +checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" dependencies = [ "bytes", "libc", @@ -517,13 +386,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.7.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" +checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] @@ -532,12 +401,6 @@ version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" @@ -552,27 +415,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.3+wasi-0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" -dependencies = [ - "wit-bindgen 0.57.1", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ - "wit-bindgen 0.51.0", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.121" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" +checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70" dependencies = [ "cfg-if", "once_cell", @@ -583,9 +437,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.121" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" +checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -593,60 +447,26 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.121" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" +checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn", + "syn 2.0.119", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.121" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" +checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf" dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap", - "wasm-encoder", - "wasmparser", -] - -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags", - "hashbrown 0.15.5", - "indexmap", - "semver", -] - [[package]] name = "winapi" version = "0.3.9" @@ -684,102 +504,8 @@ dependencies = [ "windows-link", ] -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - [[package]] name = "wit-bindgen" version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" - -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck", - "indexmap", - "prettyplease", - "syn", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", -] - -[[package]] -name = "zmij" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" From e316a9fdb3b258633bdaaaaf9f9f96ad9cf8dfee Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sun, 23 Aug 2026 16:05:45 +0200 Subject: [PATCH 05/54] do not run `simd_reduce_{min, max}` on floats natively --- .../tests/pass/intrinsics/portable-simd.rs | 130 +++++++++++------- 1 file changed, 78 insertions(+), 52 deletions(-) diff --git a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs index a3991f78b1166..4282971b1c095 100644 --- a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs +++ b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs @@ -20,6 +20,16 @@ use std::ptr; use std::simd::StdFloat; use std::simd::prelude::*; +// small hack to make type inference better +macro_rules! assert_eq { + ($a:expr, $b:expr $(,$t:tt)* $(,)?) => {{ + let a = $a; + let b = $b; + if false { let _inference = b == a; } + ::std::assert_eq!(a, b, $(,$t)*) + }} +} + // The `portable_simd` crate currently does not support f16 or f128 vectors, so we define our own. #[repr(simd, packed)] #[derive(Copy)] @@ -71,16 +81,6 @@ pub const unsafe fn simd_shuffle_const_generic( fn simd_ops_f16() { use intrinsics::*; - // small hack to make type inference better - macro_rules! assert_eq { - ($a:expr, $b:expr $(,$t:tt)*) => {{ - let a = $a; - let b = $b; - if false { let _inference = b == a; } - ::std::assert_eq!(a, b, $(,$t)*) - }} - } - let a = f16x4::splat(10.0); let b = f16x4::from_array([1.0, 2.0, 3.0, -4.0]); @@ -132,10 +132,6 @@ fn simd_ops_f16() { assert_eq!(simd_reduce_add_ordered(b, 0.0), 2.0f16); assert_eq!(simd_reduce_mul_ordered(a, 1.0), 10000.0f16); assert_eq!(simd_reduce_mul_ordered(b, 1.0), -24.0f16); - assert_eq!(simd_reduce_max(a), 10.0f16); - assert_eq!(simd_reduce_max(b), 3.0f16); - assert_eq!(simd_reduce_min(a), 10.0f16); - assert_eq!(simd_reduce_min(b), -4.0f16); assert_eq!( simd_maximum_number_nsz( @@ -144,8 +140,6 @@ fn simd_ops_f16() { ), f16x2::from_array([0.0, 0.0]) ); - assert_eq!(simd_reduce_max(f16x2::from_array([0.0, f16::NAN])), 0.0f16); - assert_eq!(simd_reduce_max(f16x2::from_array([f16::NAN, 0.0])), 0.0f16); assert_eq!( simd_minimum_number_nsz( f16x2::from_array([0.0, f16::NAN]), @@ -153,8 +147,22 @@ fn simd_ops_f16() { ), f16x2::from_array([0.0, 0.0]) ); - assert_eq!(simd_reduce_min(f16x2::from_array([0.0, f16::NAN])), 0.0f16); - assert_eq!(simd_reduce_min(f16x2::from_array([f16::NAN, 0.0])), 0.0f16); + + // FIXME(llvm): The LLVM backend rejects float `simd_reduce_{min,max}`, + // see https://github.com/llvm/llvm-project/issues/185827. + #[cfg(miri)] + { + assert_eq!(simd_reduce_max(a), 10.0f16); + assert_eq!(simd_reduce_max(b), 3.0f16); + assert_eq!(simd_reduce_min(a), 10.0f16); + assert_eq!(simd_reduce_min(b), -4.0f16); + + assert_eq!(simd_reduce_max(f16x2::from_array([0.0, f16::NAN])), 0.0f16); + assert_eq!(simd_reduce_max(f16x2::from_array([f16::NAN, 0.0])), 0.0f16); + + assert_eq!(simd_reduce_min(f16x2::from_array([0.0, f16::NAN])), 0.0f16); + assert_eq!(simd_reduce_min(f16x2::from_array([f16::NAN, 0.0])), 0.0f16); + } } } @@ -204,23 +212,33 @@ fn simd_ops_f32() { assert_eq!(b.reduce_sum(), 2.0); assert_eq!(a.reduce_product(), 100.0 * 100.0); assert_eq!(b.reduce_product(), -24.0); - assert_eq!(a.reduce_max(), 10.0); - assert_eq!(b.reduce_max(), 3.0); - assert_eq!(a.reduce_min(), 10.0); - assert_eq!(b.reduce_min(), -4.0); assert_eq!( f32x2::from_array([0.0, f32::NAN]).simd_max(f32x2::from_array([f32::NAN, 0.0])), f32x2::from_array([0.0, 0.0]) ); - assert_eq!(f32x2::from_array([0.0, f32::NAN]).reduce_max(), 0.0); - assert_eq!(f32x2::from_array([f32::NAN, 0.0]).reduce_max(), 0.0); assert_eq!( f32x2::from_array([0.0, f32::NAN]).simd_min(f32x2::from_array([f32::NAN, 0.0])), f32x2::from_array([0.0, 0.0]) ); - assert_eq!(f32x2::from_array([0.0, f32::NAN]).reduce_min(), 0.0); - assert_eq!(f32x2::from_array([f32::NAN, 0.0]).reduce_min(), 0.0); + + // FIXME(llvm): The LLVM backend rejects float `simd_reduce_{min,max}`, + // see https://github.com/llvm/llvm-project/issues/185827. + #[cfg(miri)] + unsafe { + use intrinsics::{simd_reduce_max, simd_reduce_min}; + + assert_eq!(simd_reduce_max(a), 10.0f32); + assert_eq!(simd_reduce_max(b), 3.0f32); + assert_eq!(simd_reduce_min(a), 10.0f32); + assert_eq!(simd_reduce_min(b), -4.0f32); + + assert_eq!(simd_reduce_max(f32x2::from_array([0.0, f32::NAN])), 0.0f32); + assert_eq!(simd_reduce_max(f32x2::from_array([f32::NAN, 0.0])), 0.0f32); + + assert_eq!(simd_reduce_min(f32x2::from_array([0.0, f32::NAN])), 0.0f32); + assert_eq!(simd_reduce_min(f32x2::from_array([f32::NAN, 0.0])), 0.0f32); + } } fn simd_ops_f64() { @@ -269,39 +287,39 @@ fn simd_ops_f64() { assert_eq!(b.reduce_sum(), 2.0); assert_eq!(a.reduce_product(), 100.0 * 100.0); assert_eq!(b.reduce_product(), -24.0); - assert_eq!(a.reduce_max(), 10.0); - assert_eq!(b.reduce_max(), 3.0); - assert_eq!(a.reduce_min(), 10.0); - assert_eq!(b.reduce_min(), -4.0); assert_eq!( f64x2::from_array([0.0, f64::NAN]).simd_max(f64x2::from_array([f64::NAN, 0.0])), f64x2::from_array([0.0, 0.0]) ); - assert_eq!(f64x2::from_array([0.0, f64::NAN]).reduce_max(), 0.0); - assert_eq!(f64x2::from_array([f64::NAN, 0.0]).reduce_max(), 0.0); assert_eq!( f64x2::from_array([0.0, f64::NAN]).simd_min(f64x2::from_array([f64::NAN, 0.0])), f64x2::from_array([0.0, 0.0]) ); - assert_eq!(f64x2::from_array([0.0, f64::NAN]).reduce_min(), 0.0); - assert_eq!(f64x2::from_array([f64::NAN, 0.0]).reduce_min(), 0.0); + + // FIXME(llvm): The LLVM backend rejects float `simd_reduce_{min,max}`, + // see https://github.com/llvm/llvm-project/issues/185827. + #[cfg(miri)] + unsafe { + use intrinsics::{simd_reduce_max, simd_reduce_min}; + + assert_eq!(simd_reduce_max(a), 10.0f64); + assert_eq!(simd_reduce_max(b), 3.0f64); + assert_eq!(simd_reduce_min(a), 10.0f64); + assert_eq!(simd_reduce_min(b), -4.0f64); + + assert_eq!(simd_reduce_max(f64x2::from_array([0.0, f64::NAN])), 0.0f64); + assert_eq!(simd_reduce_max(f64x2::from_array([f64::NAN, 0.0])), 0.0f64); + + assert_eq!(simd_reduce_min(f64x2::from_array([0.0, f64::NAN])), 0.0f64); + assert_eq!(simd_reduce_min(f64x2::from_array([f64::NAN, 0.0])), 0.0f64); + } } #[cfg(miri)] // FIXME(f16_f128) doesn't always work natively fn simd_ops_f128() { use intrinsics::*; - // small hack to make type inference better - macro_rules! assert_eq { - ($a:expr, $b:expr $(,$t:tt)*) => {{ - let a = $a; - let b = $b; - if false { let _inference = b == a; } - ::std::assert_eq!(a, b, $(,$t)*) - }} - } - let a = f128x4::splat(10.0); let b = f128x4::from_array([1.0, 2.0, 3.0, -4.0]); @@ -353,10 +371,6 @@ fn simd_ops_f128() { assert_eq!(simd_reduce_add_ordered(b, 0.0), 2.0f128); assert_eq!(simd_reduce_mul_ordered(a, 1.0), 10000.0f128); assert_eq!(simd_reduce_mul_ordered(b, 1.0), -24.0f128); - assert_eq!(simd_reduce_max(a), 10.0f128); - assert_eq!(simd_reduce_max(b), 3.0f128); - assert_eq!(simd_reduce_min(a), 10.0f128); - assert_eq!(simd_reduce_min(b), -4.0f128); assert_eq!( simd_maximum_number_nsz( @@ -365,8 +379,6 @@ fn simd_ops_f128() { ), f128x2::from_array([0.0, 0.0]) ); - assert_eq!(simd_reduce_max(f128x2::from_array([0.0, f128::NAN])), 0.0f128); - assert_eq!(simd_reduce_max(f128x2::from_array([f128::NAN, 0.0])), 0.0f128); assert_eq!( simd_minimum_number_nsz( f128x2::from_array([0.0, f128::NAN]), @@ -374,8 +386,22 @@ fn simd_ops_f128() { ), f128x2::from_array([0.0, 0.0]) ); - assert_eq!(simd_reduce_min(f128x2::from_array([0.0, f128::NAN])), 0.0f128); - assert_eq!(simd_reduce_min(f128x2::from_array([f128::NAN, 0.0])), 0.0f128); + + // FIXME(llvm): The LLVM backend rejects float `simd_reduce_{min,max}`, + // see https://github.com/llvm/llvm-project/issues/185827. + #[cfg(miri)] + { + assert_eq!(simd_reduce_max(a), 10.0f128); + assert_eq!(simd_reduce_max(b), 3.0f128); + assert_eq!(simd_reduce_min(a), 10.0f128); + assert_eq!(simd_reduce_min(b), -4.0f128); + + assert_eq!(simd_reduce_max(f128x2::from_array([0.0, f128::NAN])), 0.0f128); + assert_eq!(simd_reduce_max(f128x2::from_array([f128::NAN, 0.0])), 0.0f128); + + assert_eq!(simd_reduce_min(f128x2::from_array([0.0, f128::NAN])), 0.0f128); + assert_eq!(simd_reduce_min(f128x2::from_array([f128::NAN, 0.0])), 0.0f128); + } } } From 4091d1a0c65b8515d8f517f5ac249c247f411933 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sun, 23 Aug 2026 14:15:38 +0200 Subject: [PATCH 06/54] run `f16` and `f128` tests natively when reliable --- .../miri/tests/pass/intrinsics/portable-simd.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs index 4282971b1c095..eac901e7c5a56 100644 --- a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs +++ b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs @@ -8,6 +8,7 @@ intrinsics, core_intrinsics, repr_simd, + cfg_target_has_reliable_f16_f128, f16, f128 )] @@ -77,7 +78,7 @@ impl PackedSimd { #[rustc_nounwind] pub const unsafe fn simd_shuffle_const_generic(x: T, y: T) -> U; -#[cfg(miri)] // FIXME(f16_f128) doesn't always work natively +#[cfg(any(miri, target_has_reliable_f16_math))] fn simd_ops_f16() { use intrinsics::*; @@ -316,7 +317,7 @@ fn simd_ops_f64() { } } -#[cfg(miri)] // FIXME(f16_f128) doesn't always work natively +#[cfg(any(miri, target_has_reliable_f128_math))] fn simd_ops_f128() { use intrinsics::*; @@ -860,7 +861,7 @@ fn simd_gather_scatter() { } fn simd_round() { - #[cfg(miri)] // FIXME(f16_f128) doesn't always work natively + #[cfg(any(miri, target_has_reliable_f16_math))] unsafe { use intrinsics::*; @@ -928,7 +929,7 @@ fn simd_round() { f64x4::from_array([0.0, 1.0, 2.0, -4.0]) ); - #[cfg(miri)] // FIXME(f16_f128) doesn't always work natively + #[cfg(any(miri, target_has_reliable_f128_math))] unsafe { use intrinsics::*; @@ -1169,11 +1170,11 @@ fn simd_ops_non_pow2() { fn main() { simd_mask(); - #[cfg(miri)] + #[cfg(any(miri, target_has_reliable_f16_math))] simd_ops_f16(); simd_ops_f32(); simd_ops_f64(); - #[cfg(miri)] + #[cfg(any(miri, target_has_reliable_f128_math))] simd_ops_f128(); simd_ops_i32(); simd_ops_non_pow2(); From c158e179965998fdc994c82f19f6398550750271 Mon Sep 17 00:00:00 2001 From: Max Dexheimer Date: Sun, 23 Aug 2026 20:12:00 +0200 Subject: [PATCH 07/54] Add custom allocators to `(try_)map` on `Box`, `Rc`, `Arc` --- library/alloc/src/boxed.rs | 147 +++++++++---------- library/alloc/src/rc.rs | 183 +++++++++++++----------- library/alloc/src/sync.rs | 183 +++++++++++++----------- tests/ui/privacy/suggest-box-new.stderr | 4 +- 4 files changed, 265 insertions(+), 252 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 019749c77ae66..58be46690b788 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -426,82 +426,6 @@ impl Box { pub fn try_new_zeroed() -> Result>, AllocError> { Box::try_new_zeroed_in(Global) } - - /// Maps the value in a box, reusing the allocation if possible. - /// - /// `f` is called on the value in the box, and the result is returned, also boxed. - /// - /// Note: this is an associated function, which means that you have - /// to call it as `Box::map(b, f)` instead of `b.map(f)`. This - /// is so that there is no conflict with a method on the inner type. - /// - /// # Examples - /// - /// ``` - /// #![feature(smart_pointer_try_map)] - /// - /// let b = Box::new(7); - /// let new = Box::map(b, |i| i + 7); - /// assert_eq!(*new, 14); - /// ``` - #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "smart_pointer_try_map", issue = "144419")] - pub fn map(this: Self, f: impl FnOnce(T) -> U) -> Box { - if size_of::() == size_of::() && align_of::() == align_of::() { - let (value, allocation) = Box::take(this); - Box::write( - unsafe { mem::transmute::>, Box>>(allocation) }, - f(value), - ) - } else { - Box::new(f(*this)) - } - } - - /// Attempts to map the value in a box, reusing the allocation if possible. - /// - /// `f` is called on the value in the box, and if the operation succeeds, the result is - /// returned, also boxed. - /// - /// Note: this is an associated function, which means that you have - /// to call it as `Box::try_map(b, f)` instead of `b.try_map(f)`. This - /// is so that there is no conflict with a method on the inner type. - /// - /// # Examples - /// - /// ``` - /// #![feature(smart_pointer_try_map)] - /// - /// let b = Box::new(7); - /// let new = Box::try_map(b, u32::try_from).unwrap(); - /// assert_eq!(*new, 7); - /// ``` - #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "smart_pointer_try_map", issue = "144419")] - pub fn try_map( - this: Self, - f: impl FnOnce(T) -> R, - ) -> >>::TryType - where - R: Try, - R::Residual: Residual>, - { - if size_of::() == size_of::() && align_of::() == align_of::() { - let (value, allocation) = Box::take(this); - try { - Box::write( - unsafe { - mem::transmute::>, Box>>( - allocation, - ) - }, - f(value)?, - ) - } - } else { - try { Box::new(f(*this)?) } - } - } } impl Box { @@ -776,6 +700,77 @@ impl Box { (value, uninit) } } + + /// Maps the value in a box, reusing the allocation if possible. + /// + /// `f` is called on the value in the box, and the result is returned, also boxed. + /// + /// Note: this is an associated function, which means that you have + /// to call it as `Box::map(b, f)` instead of `b.map(f)`. This + /// is so that there is no conflict with a method on the inner type. + /// + /// # Examples + /// + /// ``` + /// #![feature(smart_pointer_try_map)] + /// + /// let b = Box::new(7); + /// let new = Box::map(b, |i| i + 7); + /// assert_eq!(*new, 14); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "smart_pointer_try_map", issue = "144419")] + pub fn map(this: Self, f: impl FnOnce(T) -> U) -> Box { + let (value, allocation) = Box::take(this); + let (raw, alloc) = Box::into_non_null_with_allocator(allocation); + if size_of::() == size_of::() && align_of::() == align_of::() { + let allocation = unsafe { Box::from_non_null_in(raw.cast::>(), alloc) }; + Box::write(allocation, f(value)) + } else { + unsafe { alloc.deallocate(raw.cast(), Layout::for_value(&value)) } + Box::new_in(f(value), alloc) + } + } + + /// Attempts to map the value in a box, reusing the allocation if possible. + /// + /// `f` is called on the value in the box, and if the operation succeeds, the result is + /// returned, also boxed. + /// + /// Note: this is an associated function, which means that you have + /// to call it as `Box::try_map(b, f)` instead of `b.try_map(f)`. This + /// is so that there is no conflict with a method on the inner type. + /// + /// # Examples + /// + /// ``` + /// #![feature(smart_pointer_try_map)] + /// + /// let b = Box::new(7); + /// let new = Box::try_map(b, u32::try_from).unwrap(); + /// assert_eq!(*new, 7); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "smart_pointer_try_map", issue = "144419")] + pub fn try_map( + this: Self, + f: impl FnOnce(T) -> R, + ) -> >>::TryType + where + R: Try, + R::Residual: Residual>, + { + let (value, allocation) = Box::take(this); + let (raw, alloc) = Box::into_non_null_with_allocator(allocation); + if size_of::() == size_of::() && align_of::() == align_of::() { + let allocation = + unsafe { Box::from_non_null_in(raw.cast::>(), alloc) }; + try { Box::write(allocation, f(value)?) } + } else { + unsafe { alloc.deallocate(raw.cast(), Layout::for_value(&value)) } + try { Box::new_in(f(value)?, alloc) } + } + } } impl Box { diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index e4a803f28e121..8d954d90c615d 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -651,93 +651,6 @@ impl Rc { pub fn pin(value: T) -> Pin> { unsafe { Pin::new_unchecked(Rc::new(value)) } } - - /// Maps the value in an `Rc`, reusing the allocation if possible. - /// - /// `f` is called on a reference to the value in the `Rc`, and the result is returned, also in - /// an `Rc`. - /// - /// Note: this is an associated function, which means that you have - /// to call it as `Rc::map(r, f)` instead of `r.map(f)`. This - /// is so that there is no conflict with a method on the inner type. - /// - /// # Examples - /// - /// ``` - /// #![feature(smart_pointer_try_map)] - /// - /// use std::rc::Rc; - /// - /// let r = Rc::new(7); - /// let new = Rc::map(r, |i| i + 7); - /// assert_eq!(*new, 14); - /// ``` - #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "smart_pointer_try_map", issue = "144419")] - pub fn map(this: Self, f: impl FnOnce(&T) -> U) -> Rc { - if size_of::() == size_of::() - && align_of::() == align_of::() - && Rc::is_unique(&this) - { - unsafe { - let ptr = Rc::into_raw(this); - let value = ptr.read(); - let mut allocation = Rc::from_raw(ptr.cast::>()); - - Rc::get_mut_unchecked(&mut allocation).write(f(&value)); - allocation.assume_init() - } - } else { - Rc::new(f(&*this)) - } - } - - /// Attempts to map the value in an `Rc`, reusing the allocation if possible. - /// - /// `f` is called on a reference to the value in the `Rc`, and if the operation succeeds, the - /// result is returned, also in an `Rc`. - /// - /// Note: this is an associated function, which means that you have - /// to call it as `Rc::try_map(r, f)` instead of `r.try_map(f)`. This - /// is so that there is no conflict with a method on the inner type. - /// - /// # Examples - /// - /// ``` - /// #![feature(smart_pointer_try_map)] - /// - /// use std::rc::Rc; - /// - /// let b = Rc::new(7); - /// let new = Rc::try_map(b, |&i| u32::try_from(i)).unwrap(); - /// assert_eq!(*new, 7); - /// ``` - #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "smart_pointer_try_map", issue = "144419")] - pub fn try_map( - this: Self, - f: impl FnOnce(&T) -> R, - ) -> >>::TryType - where - R: Try, - R::Residual: Residual>, - { - if size_of::() == size_of::() - && align_of::() == align_of::() - && Rc::is_unique(&this) - { - unsafe { - let ptr = Rc::into_raw(this); - let value = ptr.read(); - let mut allocation = Rc::from_raw(ptr.cast::>()); - - Rc::get_mut_unchecked(&mut allocation).write(f(&value)?); - try { allocation.assume_init() } - } - } else { - try { Rc::new(f(&*this)?) } - } - } } impl Rc { @@ -1107,6 +1020,102 @@ impl Rc { pub fn into_inner(this: Self) -> Option { Rc::try_unwrap(this).ok() } + + /// Maps the value in an `Rc`, reusing the allocation if possible. + /// + /// `f` is called on a reference to the value in the `Rc`, and the result is returned, also in + /// an `Rc`. + /// + /// Note: this is an associated function, which means that you have + /// to call it as `Rc::map(r, f)` instead of `r.map(f)`. This + /// is so that there is no conflict with a method on the inner type. + /// + /// # Examples + /// + /// ``` + /// #![feature(smart_pointer_try_map)] + /// + /// use std::rc::Rc; + /// + /// let r = Rc::new(7); + /// let new = Rc::map(r, |i| i + 7); + /// assert_eq!(*new, 14); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "smart_pointer_try_map", issue = "144419")] + pub fn map(this: Self, f: impl FnOnce(&T) -> U) -> Rc { + if size_of::() == size_of::() + && align_of::() == align_of::() + && Rc::is_unique(&this) + { + unsafe { + let (ptr, alloc) = Rc::into_raw_with_allocator(this); + let value = ptr.read(); + let mut allocation = Rc::from_raw_in(ptr.cast::>(), alloc); + + Rc::get_mut_unchecked(&mut allocation).write(f(&value)); + allocation.assume_init() + } + } else { + let output = f(&*this); + let (ptr, alloc) = Rc::into_raw_with_allocator(this); + unsafe { Rc::decrement_strong_count_in(ptr, &alloc) } + + Rc::new_in(output, alloc) + } + } + + /// Attempts to map the value in an `Rc`, reusing the allocation if possible. + /// + /// `f` is called on a reference to the value in the `Rc`, and if the operation succeeds, the + /// result is returned, also in an `Rc`. + /// + /// Note: this is an associated function, which means that you have + /// to call it as `Rc::try_map(r, f)` instead of `r.try_map(f)`. This + /// is so that there is no conflict with a method on the inner type. + /// + /// # Examples + /// + /// ``` + /// #![feature(smart_pointer_try_map)] + /// + /// use std::rc::Rc; + /// + /// let b = Rc::new(7); + /// let new = Rc::try_map(b, |&i| u32::try_from(i)).unwrap(); + /// assert_eq!(*new, 7); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "smart_pointer_try_map", issue = "144419")] + pub fn try_map( + this: Self, + f: impl FnOnce(&T) -> R, + ) -> >>::TryType + where + R: Try, + R::Residual: Residual>, + { + if size_of::() == size_of::() + && align_of::() == align_of::() + && Rc::is_unique(&this) + { + unsafe { + let (ptr, alloc) = Rc::into_raw_with_allocator(this); + let value = ptr.read(); + let mut allocation = + Rc::from_raw_in(ptr.cast::>(), alloc); + + Rc::get_mut_unchecked(&mut allocation).write(f(&value)?); + try { allocation.assume_init() } + } + } else { + let output = f(&*this)?; + let (ptr, alloc) = Rc::into_raw_with_allocator(this); + unsafe { Rc::decrement_strong_count_in(ptr, &alloc) } + + try { Rc::new_in(output, alloc) } + } + } } impl Rc<[T]> { diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 625a29dd9b7a0..e72449d670ed2 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -673,93 +673,6 @@ impl Arc { )?)) } } - - /// Maps the value in an `Arc`, reusing the allocation if possible. - /// - /// `f` is called on a reference to the value in the `Arc`, and the result is returned, also in - /// an `Arc`. - /// - /// Note: this is an associated function, which means that you have - /// to call it as `Arc::map(a, f)` instead of `r.map(a)`. This - /// is so that there is no conflict with a method on the inner type. - /// - /// # Examples - /// - /// ``` - /// #![feature(smart_pointer_try_map)] - /// - /// use std::sync::Arc; - /// - /// let r = Arc::new(7); - /// let new = Arc::map(r, |i| i + 7); - /// assert_eq!(*new, 14); - /// ``` - #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "smart_pointer_try_map", issue = "144419")] - pub fn map(this: Self, f: impl FnOnce(&T) -> U) -> Arc { - if size_of::() == size_of::() - && align_of::() == align_of::() - && Arc::is_unique(&this) - { - unsafe { - let ptr = Arc::into_raw(this); - let value = ptr.read(); - let mut allocation = Arc::from_raw(ptr.cast::>()); - - Arc::get_mut_unchecked(&mut allocation).write(f(&value)); - allocation.assume_init() - } - } else { - Arc::new(f(&*this)) - } - } - - /// Attempts to map the value in an `Arc`, reusing the allocation if possible. - /// - /// `f` is called on a reference to the value in the `Arc`, and if the operation succeeds, the - /// result is returned, also in an `Arc`. - /// - /// Note: this is an associated function, which means that you have - /// to call it as `Arc::try_map(a, f)` instead of `a.try_map(f)`. This - /// is so that there is no conflict with a method on the inner type. - /// - /// # Examples - /// - /// ``` - /// #![feature(smart_pointer_try_map)] - /// - /// use std::sync::Arc; - /// - /// let b = Arc::new(7); - /// let new = Arc::try_map(b, |&i| u32::try_from(i)).unwrap(); - /// assert_eq!(*new, 7); - /// ``` - #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "smart_pointer_try_map", issue = "144419")] - pub fn try_map( - this: Self, - f: impl FnOnce(&T) -> R, - ) -> >>::TryType - where - R: Try, - R::Residual: Residual>, - { - if size_of::() == size_of::() - && align_of::() == align_of::() - && Arc::is_unique(&this) - { - unsafe { - let ptr = Arc::into_raw(this); - let value = ptr.read(); - let mut allocation = Arc::from_raw(ptr.cast::>()); - - Arc::get_mut_unchecked(&mut allocation).write(f(&value)?); - try { allocation.assume_init() } - } - } else { - try { Arc::new(f(&*this)?) } - } - } } impl Arc { @@ -1263,6 +1176,102 @@ impl Arc { Some(inner) } + + /// Maps the value in an `Arc`, reusing the allocation if possible. + /// + /// `f` is called on a reference to the value in the `Arc`, and the result is returned, also in + /// an `Arc`. + /// + /// Note: this is an associated function, which means that you have + /// to call it as `Arc::map(a, f)` instead of `r.map(a)`. This + /// is so that there is no conflict with a method on the inner type. + /// + /// # Examples + /// + /// ``` + /// #![feature(smart_pointer_try_map)] + /// + /// use std::sync::Arc; + /// + /// let r = Arc::new(7); + /// let new = Arc::map(r, |i| i + 7); + /// assert_eq!(*new, 14); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "smart_pointer_try_map", issue = "144419")] + pub fn map(this: Self, f: impl FnOnce(&T) -> U) -> Arc { + if size_of::() == size_of::() + && align_of::() == align_of::() + && Arc::is_unique(&this) + { + unsafe { + let (ptr, alloc) = Arc::into_raw_with_allocator(this); + let value = ptr.read(); + let mut allocation = Arc::from_raw_in(ptr.cast::>(), alloc); + + Arc::get_mut_unchecked(&mut allocation).write(f(&value)); + allocation.assume_init() + } + } else { + let output = f(&*this); + let (ptr, alloc) = Arc::into_raw_with_allocator(this); + unsafe { Arc::decrement_strong_count_in(ptr, &alloc) } + + Arc::new_in(output, alloc) + } + } + + /// Attempts to map the value in an `Arc`, reusing the allocation if possible. + /// + /// `f` is called on a reference to the value in the `Arc`, and if the operation succeeds, the + /// result is returned, also in an `Arc`. + /// + /// Note: this is an associated function, which means that you have + /// to call it as `Arc::try_map(a, f)` instead of `a.try_map(f)`. This + /// is so that there is no conflict with a method on the inner type. + /// + /// # Examples + /// + /// ``` + /// #![feature(smart_pointer_try_map)] + /// + /// use std::sync::Arc; + /// + /// let b = Arc::new(7); + /// let new = Arc::try_map(b, |&i| u32::try_from(i)).unwrap(); + /// assert_eq!(*new, 7); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "smart_pointer_try_map", issue = "144419")] + pub fn try_map( + this: Self, + f: impl FnOnce(&T) -> R, + ) -> >>::TryType + where + R: Try, + R::Residual: Residual>, + { + if size_of::() == size_of::() + && align_of::() == align_of::() + && Arc::is_unique(&this) + { + unsafe { + let (ptr, alloc) = Arc::into_raw_with_allocator(this); + let value = ptr.read(); + let mut allocation = + Arc::from_raw_in(ptr.cast::>(), alloc); + + Arc::get_mut_unchecked(&mut allocation).write(f(&value)?); + try { allocation.assume_init() } + } + } else { + let output = f(&*this)?; + let (ptr, alloc) = Arc::into_raw_with_allocator(this); + unsafe { Arc::decrement_strong_count_in(ptr, &alloc) } + + try { Arc::new_in(output, alloc) } + } + } } impl Arc<[T]> { diff --git a/tests/ui/privacy/suggest-box-new.stderr b/tests/ui/privacy/suggest-box-new.stderr index 8df8346f772ba..32525a41f946c 100644 --- a/tests/ui/privacy/suggest-box-new.stderr +++ b/tests/ui/privacy/suggest-box-new.stderr @@ -147,10 +147,10 @@ LL - let _ = Box:: {}; LL + let _ = Box::::new_in(_, _); | LL - let _ = Box:: {}; -LL + let _ = Box::::map(_, _); +LL + let _ = Box::::into_inner(_); | LL - let _ = Box:: {}; -LL + let _ = Box::::into_inner(_); +LL + let _ = Box::::map(_, _); | = and 7 other candidates help: consider using the `Default` trait From 3907f659d9238b9104a52ce7f50529659989ae9a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 23 Aug 2026 20:00:02 +0200 Subject: [PATCH 08/54] port all variadic functions to strict signature checking --- src/tools/miri/src/shims/sig.rs | 169 +++++++++++------- src/tools/miri/src/shims/unix/fd.rs | 19 +- .../miri/src/shims/unix/foreign_items.rs | 37 +++- src/tools/miri/src/shims/unix/fs.rs | 10 +- .../src/shims/unix/linux/foreign_items.rs | 16 +- .../miri/src/shims/unix/linux_like/sync.rs | 37 ++-- .../miri/src/shims/unix/linux_like/syscall.rs | 25 ++- .../miri/src/shims/unix/linux_like/thread.rs | 18 +- src/tools/miri/src/shims/unix/tcp_socket.rs | 7 +- .../miri/src/shims/unix/virtual_socket.rs | 7 +- .../shims/non_vararg_signature_mismatch.rs | 2 +- .../non_vararg_signature_mismatch.stderr | 2 +- .../tests/fail/shims/wrong_fixed_arg_count.rs | 2 +- .../fail/shims/wrong_fixed_arg_count.stderr | 2 +- 14 files changed, 228 insertions(+), 125 deletions(-) diff --git a/src/tools/miri/src/shims/sig.rs b/src/tools/miri/src/shims/sig.rs index 6bf1873d1d670..e044ed09db8a6 100644 --- a/src/tools/miri/src/shims/sig.rs +++ b/src/tools/miri/src/shims/sig.rs @@ -13,6 +13,7 @@ pub struct ShimSig<'tcx, const ARGS: usize> { pub args: [Ty<'tcx>; ARGS], pub ret: Ty<'tcx>, pub nounwind: bool, + pub c_variadic: bool, } /// Construct a `ShimSig` with convenient syntax: @@ -34,6 +35,21 @@ macro_rules! shim_sig { args: shim_sig_args_sep!(this, [$($args)*]), ret: shim_sig_arg!(this, $($ret)*), nounwind: false, + c_variadic: false, + } + }; +} + +/// Same as `shim_sig!` but declares a variadic function. The signature is for the fixed part. +#[macro_export] +macro_rules! shim_sig_variadic { + (extern $abi:literal fn($($args:tt)*) -> $($ret:tt)*) => { + |this| $crate::shims::sig::ShimSig { + abi: std::str::FromStr::from_str($abi).expect("incorrect abi specified"), + args: shim_sig_args_sep!(this, [$($args)*]), + ret: shim_sig_arg!(this, $($ret)*), + nounwind: true, + c_variadic: true, } }; } @@ -47,10 +63,19 @@ macro_rules! shim_sig_nounwind { args: shim_sig_args_sep!(this, [$($args)*]), ret: shim_sig_arg!(this, $($ret)*), nounwind: true, + c_variadic: false, } }; } +/// Computes a list of types for varargs, using the same syntax as `shim_sig!`. +#[macro_export] +macro_rules! shim_varargs { + ($($args:tt)*) => { + |this| shim_sig_args_sep!(this, [$($args)*]) + }; +} + /// Helper for `shim_sig!`. /// /// Groups tokens into comma-separated chunks and calls the provided macro on them. @@ -86,7 +111,7 @@ macro_rules! shim_sig_args_sep { (@ $this:ident [$($final:tt)*] [$($collected:tt)+] ) => { [$($final)* shim_sig_arg!($this, $($collected)*)] }; - // No more tokens - emit final output. + // No more tokens, empty collector - emit final output. (@ $this:ident [$($final:tt)*] [] ) => { [$($final)*] }; @@ -169,6 +194,19 @@ macro_rules! shim_sig_arg { } } +impl<'tcx, const ARGS: usize> ShimSig<'tcx, ARGS> { + fn as_abi(&self, ecx: &MiriInterpCx<'tcx>) -> &FnAbi<'tcx, Ty<'tcx>> { + let mut inputs_and_output = Vec::with_capacity(ARGS.strict_add(1)); + inputs_and_output.extend(&self.args); + inputs_and_output.push(self.ret); + let fn_sig_binder = Binder::dummy(FnSig { + inputs_and_output: ecx.machine.tcx.mk_type_list(&inputs_and_output), + fn_sig_kind: FnSigKind::default().set_c_variadic(self.c_variadic).set_abi(self.abi), + }); + ecx.fn_abi_of_fn_ptr(fn_sig_binder, Default::default()).unwrap() + } +} + /// Helper function to compare two ABIs. fn check_shim_abi<'tcx>( this: &MiriInterpCx<'tcx>, @@ -203,8 +241,9 @@ fn check_shim_abi<'tcx>( if callee_abi.fixed_count != caller_abi.fixed_count { throw_ub_format!( - "ABI mismatch: calling `{link_name}` which takes {} argument{}, but {} argument{} given", + "ABI mismatch: calling `{link_name}` which takes {} {}argument{}, but {} argument{} given", callee_abi.fixed_count, + if callee_abi.c_variadic { "fixed (non-variadic) " } else { "" }, if callee_abi.fixed_count == 1 { "" } else { "s" }, caller_abi.fixed_count, if caller_abi.fixed_count == 1 { " was" } else { "s were" }, @@ -233,6 +272,14 @@ fn check_shim_abi<'tcx>( interp_ok(()) } +/// Represents a tail of variadic arguments that have not yet been checked. +// Deliberately not `Copy` so that we don't consume the same vararg multiple times accidentally. +pub struct Varargs<'tcx, 'a> { + args: &'a [OpTy<'tcx>], + /// Number of variadic arguments that have already been taken, for error messages. + already_gone: usize, +} + impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Ensure the given symbol is not exported by the program. @@ -291,27 +338,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Check that the given `caller_fn_abi` matches the expected ABI described by `shim_sig`, and /// then returns the list of arguments. fn check_shim_sig<'a, const N: usize>( - &mut self, + &self, shim_sig: fn(&MiriInterpCx<'tcx>) -> ShimSig<'tcx, N>, link_name: Symbol, caller_fn_abi: &FnAbi<'tcx, Ty<'tcx>>, caller_args: &'a [OpTy<'tcx>], ) -> InterpResult<'tcx, &'a [OpTy<'tcx>; N]> { - let this = self.eval_context_mut(); - let shim_sig = shim_sig(this); + let this = self.eval_context_ref(); - // Compute full callee ABI. - let mut inputs_and_output = Vec::with_capacity(N.strict_add(1)); - inputs_and_output.extend(&shim_sig.args); - inputs_and_output.push(shim_sig.ret); - let fn_sig_binder = Binder::dummy(FnSig { - inputs_and_output: this.machine.tcx.mk_type_list(&inputs_and_output), - // Safety and splatted do not matter for the ABI. - fn_sig_kind: FnSigKind::default() - .set_abi(shim_sig.abi) - .set_safety(rustc_hir::Safety::Safe), - }); - let callee_fn_abi = this.fn_abi_of_fn_ptr(fn_sig_binder, Default::default())?; + // Compute callee ABI. + let shim_sig = shim_sig(this); + assert!(!shim_sig.c_variadic); + let callee_fn_abi = shim_sig.as_abi(this); // Check everything. check_shim_abi(this, link_name, callee_fn_abi, shim_sig.nounwind, caller_fn_abi)?; @@ -324,42 +362,63 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { unreachable!() } - /// Check shim for variadic function. - /// Returns a tuple that consisting of an array of fixed args, and a slice of varargs. - fn check_shim_sig_variadic_lenient<'a, const N: usize>( - &mut self, - abi: &FnAbi<'tcx, Ty<'tcx>>, - exp_abi: CanonAbi, + /// Check that the given `caller_fn_abi` matches the expected ABI described by `shim_sig`, and + /// then returns the list of fixed and variadic arguments in separate lists. + fn check_shim_sig_variadic<'a, const N: usize>( + &self, + shim_sig: fn(&MiriInterpCx<'tcx>) -> ShimSig<'tcx, N>, link_name: Symbol, - args: &'a [OpTy<'tcx>], - ) -> InterpResult<'tcx, (&'a [OpTy<'tcx>; N], &'a [OpTy<'tcx>])> - where - &'a [OpTy<'tcx>; N]: TryFrom<&'a [OpTy<'tcx>]>, - { - self.check_shim_symbol_clash(link_name)?; + caller_fn_abi: &FnAbi<'tcx, Ty<'tcx>>, + caller_args: &'a [OpTy<'tcx>], + ) -> InterpResult<'tcx, (&'a [OpTy<'tcx>; N], Varargs<'tcx, 'a>)> { + let this = self.eval_context_ref(); - if abi.conv != exp_abi { - throw_ub_format!( - r#"calling a function with calling convention "{exp_abi}" using caller calling convention "{}""#, - abi.conv - ); - } - if !abi.c_variadic { - throw_ub_format!( - "calling a variadic function with a non-variadic caller-side signature" - ); + // Compute callee ABI. + let shim_sig = shim_sig(this); + assert!(shim_sig.c_variadic); + let callee_fn_abi = shim_sig.as_abi(this); + + // Check everything. + check_shim_abi(this, link_name, callee_fn_abi, shim_sig.nounwind, caller_fn_abi)?; + this.check_shim_symbol_clash(link_name)?; + + // Return arguments. + if let Some((fixed, var)) = caller_args.split_first_chunk() { + return interp_ok((fixed, Varargs { args: var, already_gone: 0 })); } - if abi.fixed_count != u32::try_from(N).unwrap() { + unreachable!() + } + + /// Fetches `N` arguments from `varargs`, checking their types. + /// Also returns the remaining varargs. + fn check_varargs<'a, const N: usize>( + &self, + tys: fn(&MiriInterpCx<'tcx>) -> [Ty<'tcx>; N], + varargs: Varargs<'tcx, 'a>, + fn_name: &str, + ) -> InterpResult<'tcx, (&'a [OpTy<'tcx>; N], Varargs<'tcx, 'a>)> { + let this = self.eval_context_ref(); + let tys = tys(this); + + let Some((now, tail)) = varargs.args.split_first_chunk::() else { throw_ub_format!( - "incorrect number of fixed arguments for variadic function `{}`: got {}, expected {N}", - link_name.as_str(), - abi.fixed_count + "not enough variadic arguments for `{fn_name}`: got {}, expected at least {}", + varargs.already_gone.strict_add(varargs.args.len()), + varargs.already_gone.strict_add(N), ) + }; + + for (n, (caller_gave, callee_expected)) in now.iter().zip(tys).enumerate() { + // Check ABI compatibility. This is less strict than `next_arg` but we're also + // not limited to just a few simple types. + let callee_expected = this.layout_of(callee_expected)?; + + // FIXME: check compatibility once + // landed. + let _unused = (n, caller_gave, callee_expected); } - if let Some(args) = args.split_first_chunk() { - return interp_ok(args); - } - panic!("mismatch between signature and `args` slice"); + + interp_ok((now, Varargs { args: tail, already_gone: varargs.already_gone.strict_add(N) })) } /// Check that the given function has the expected amount of arguments, and then @@ -385,19 +444,3 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) } } - -/// Check that the number of varargs is at least the minimum what we expect. -/// Fixed args should not be included. -pub fn check_min_vararg_count<'a, 'tcx, const N: usize>( - name: &'a str, - args: &'a [OpTy<'tcx>], -) -> InterpResult<'tcx, &'a [OpTy<'tcx>; N]> { - if let Some((ops, _)) = args.split_first_chunk() { - return interp_ok(ops); - } - throw_ub_format!( - "not enough variadic arguments for `{name}`: got {}, expected at least {}", - args.len(), - N - ) -} diff --git a/src/tools/miri/src/shims/unix/fd.rs b/src/tools/miri/src/shims/unix/fd.rs index fbc71c05058eb..c0278d539d877 100644 --- a/src/tools/miri/src/shims/unix/fd.rs +++ b/src/tools/miri/src/shims/unix/fd.rs @@ -10,7 +10,7 @@ use rustc_target::spec::Os; use crate::shims::FileDescriptionRef; use crate::shims::files::{DynFileDescriptionRef, FdNum, FileDescription}; -use crate::shims::sig::check_min_vararg_count; +use crate::shims::sig::Varargs; use crate::shims::unix::socket::UnixSocketFileDescription; use crate::shims::unix::*; use crate::*; @@ -71,7 +71,7 @@ pub trait UnixFileDescription: FileDescription { fn ioctl<'tcx>( &self, _op: Scalar, - _arg: Option<&OpTy<'tcx>>, + _args: Varargs<'tcx, '_>, _ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx, i32> { throw_unsup_format!("cannot use ioctl on {}", self.name()); @@ -181,16 +181,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { &mut self, fd: &OpTy<'tcx>, op: &OpTy<'tcx>, - varargs: &[OpTy<'tcx>], + varargs: Varargs<'tcx, '_>, ) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); let fd = this.read_scalar(fd)?.to_i32()?; let op = this.read_scalar(op)?; - // There is at most one relevant variadic argument. - // It exists depending on the device and the opcode and thus we can't - // use `check_min_vararg_count` here. - let arg = varargs.first(); let Some(fd) = this.machine.fds.get(fd) else { return this.set_errno_and_return_neg1_i32(LibcError("EBADF")); @@ -206,7 +202,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Since some ioctl operations use the return value as an output parameter, we cannot strictly use the convention of // zero indicating success and -1 indicating an error. - let return_value = fd.as_unix(this).ioctl(op, arg, this)?; + let return_value = fd.as_unix(this).ioctl(op, varargs, this)?; interp_ok(Scalar::from_i32(return_value)) } @@ -214,7 +210,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { &mut self, fd_num: &OpTy<'tcx>, cmd: &OpTy<'tcx>, - varargs: &[OpTy<'tcx>], + varargs: Varargs<'tcx, '_>, ) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); @@ -251,7 +247,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "fcntl(fd, F_DUPFD_CLOEXEC, ...)" }; - let [start] = check_min_vararg_count(cmd_name, varargs)?; + let ([start], _) = this.check_varargs(shim_varargs![i32], varargs, cmd_name)?; let start = this.read_scalar(start)?.to_i32()?; if let Some(fd) = this.machine.fds.get(fd_num) { @@ -274,7 +270,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { return this.set_errno_and_return_neg1_i32(LibcError("EBADF")); }; - let [flag] = check_min_vararg_count("fcntl(fd, F_SETFL, ...)", varargs)?; + let ([flag], _) = + this.check_varargs(shim_varargs![i32], varargs, "fcntl(fd, F_SETFL, ...)")?; let flag = this.read_scalar(flag)?.to_i32()?; // Ignore flags that never get stored by SETFL. diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index 0bb154a549832..e96b73bbf7247 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -6,7 +6,7 @@ use rustc_abi::{CanonAbi, Size}; use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; -use rustc_target::spec::Os; +use rustc_target::spec::{Env, Os}; use self::shims::unix::android::foreign_items as android; use self::shims::unix::freebsd::foreign_items as freebsd; @@ -315,8 +315,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "fcntl" => { - let ([fd_num, cmd], varargs) = - this.check_shim_sig_variadic_lenient(abi, CanonAbi::C, link_name, args)?; + let ([fd_num, cmd], varargs) = this.check_shim_sig_variadic( + shim_sig_variadic!(extern "C" fn(i32, i32) -> i32), + link_name, + abi, + args, + )?; let result = this.fcntl(fd_num, cmd, varargs)?; this.write_scalar(result, dest)?; } @@ -362,8 +366,23 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "ioctl" => { - let ([fd, op], varargs) = - this.check_shim_sig_variadic_lenient(abi, CanonAbi::C, link_name, args)?; + // The type of `op` depends on the libc. :( + // glibc, BSD use `unsigned long`, the rest uses `int`. + let op_is_ulong = match this.tcx.sess.target.os { + Os::FreeBsd | Os::NetBsd | Os::MacOs => true, + Os::Linux if this.tcx.sess.target.env == Env::Gnu => true, + _ => false, + }; + let ([fd, op], varargs) = this.check_shim_sig_variadic( + if op_is_ulong { + shim_sig_variadic!(extern "C" fn(i32, usize) -> i32) + } else { + shim_sig_variadic!(extern "C" fn(i32, i32) -> i32) + }, + link_name, + abi, + args, + )?; let result = this.ioctl(fd, op, varargs)?; this.write_scalar(result, dest)?; } @@ -372,8 +391,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "open" => { // `open` is variadic, the third argument is only present when the second argument // has O_CREAT (or on linux O_TMPFILE, but miri doesn't support that) set - let ([path_raw, flag], varargs) = - this.check_shim_sig_variadic_lenient(abi, CanonAbi::C, link_name, args)?; + let ([path_raw, flag], varargs) = this.check_shim_sig_variadic( + shim_sig_variadic!(extern "C" fn(*_, i32) -> i32), + link_name, + abi, + args, + )?; let result = this.open(path_raw, flag, varargs)?; this.write_scalar(result, dest)?; } diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index 8594e7ea35e4e..427fec0c84405 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -15,7 +15,7 @@ use rustc_target::spec::Os; use self::shims::time::system_time_to_duration; use crate::shims::files::FileHandle; use crate::shims::os_str::bytes_to_os_str; -use crate::shims::sig::check_min_vararg_count; +use crate::shims::sig::Varargs; use crate::shims::unix::fd::{FlockOp, UnixFileDescription}; use crate::*; @@ -399,7 +399,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { &mut self, path_raw: &OpTy<'tcx>, flag: &OpTy<'tcx>, - varargs: &[OpTy<'tcx>], + varargs: Varargs<'tcx, '_>, ) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); @@ -463,7 +463,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Get the mode. On macOS, the argument type `mode_t` is actually `u16`, but // C integer promotion rules mean that on the ABI level, it gets passed as `u32` // (see https://github.com/rust-lang/rust/issues/71915). - let [mode] = check_min_vararg_count("open(pathname, O_CREAT, ...)", varargs)?; + let ([mode], _) = this.check_varargs( + shim_varargs![libc::mode_t], + varargs, + "open(pathname, O_CREAT, ...)", + )?; let mode = this.read_scalar(mode)?.to_u32()?; #[cfg(unix)] diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs index 61d32c599680f..2c1f891ceaff9 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -40,8 +40,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "open64" => { // `open64` is variadic, the third argument is only present when the second argument // has O_CREAT (or on linux O_TMPFILE, but miri doesn't support that) set - let ([path_raw, flag], varargs) = - this.check_shim_sig_variadic_lenient(abi, CanonAbi::C, link_name, args)?; + let ([path_raw, flag], varargs) = this.check_shim_sig_variadic( + shim_sig_variadic!(extern "C" fn(*_, i32) -> i32), + link_name, + abi, + args, + )?; let result = this.open(path_raw, flag, varargs)?; this.write_scalar(result, dest)?; } @@ -253,8 +257,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(ptr, dest)?; } "mremap" => { - let ([old_address, old_size, new_size, flags], _) = - this.check_shim_sig_variadic_lenient(abi, CanonAbi::C, link_name, args)?; + let ([old_address, old_size, new_size, flags], _) = this.check_shim_sig_variadic( + shim_sig_variadic!(extern "C" fn(*_, usize, usize, i32) -> *_), + link_name, + abi, + args, + )?; let ptr = this.mremap(old_address, old_size, new_size, flags)?; this.write_scalar(ptr, dest)?; } diff --git a/src/tools/miri/src/shims/unix/linux_like/sync.rs b/src/tools/miri/src/shims/unix/linux_like/sync.rs index 87d73d7f2e286..ebbaa836007aa 100644 --- a/src/tools/miri/src/shims/unix/linux_like/sync.rs +++ b/src/tools/miri/src/shims/unix/linux_like/sync.rs @@ -1,5 +1,5 @@ use crate::concurrency::sync::{FutexRef, SyncObj}; -use crate::shims::sig::check_min_vararg_count; +use crate::shims::sig::Varargs; use crate::*; struct LinuxFutex { @@ -12,10 +12,11 @@ impl SyncObj for LinuxFutex {} /// `args` is the arguments *including* the syscall number. pub fn futex<'tcx>( ecx: &mut MiriInterpCx<'tcx>, - varargs: &[OpTy<'tcx>], + varargs: Varargs<'tcx, '_>, dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx> { - let [addr, op, val] = check_min_vararg_count("`syscall(SYS_futex, ...)`", varargs)?; + let ([addr, op, val], varargs) = + ecx.check_varargs(shim_varargs![*_, i32, u32], varargs, "syscall(SYS_futex, ...)")?; // See for docs. // The first three arguments (after the syscall number itself) are the same to all futex operations: @@ -50,16 +51,19 @@ pub fn futex<'tcx>( let wait_bitset = op & !futex_realtime == futex_wait_bitset; let (timeout, bitset) = if wait_bitset { - let [_, _, _, timeout, uaddr2, bitset] = check_min_vararg_count( - "`syscall(SYS_futex, FUTEX_WAIT_BITSET, ...)`", + let ([timeout, uaddr2, bitset], _) = ecx.check_varargs( + shim_varargs![*_, *_, u32], varargs, + "syscall(SYS_futex, ...)", )?; - let _timeout = ecx.read_pointer(timeout)?; - let _uaddr2 = ecx.read_pointer(uaddr2)?; + let uaddr2 = ecx.read_pointer(uaddr2)?; + if !ecx.ptr_is_null(uaddr2)? { + throw_ub_format!("`uaddr2` pointer must be null for `FUTEX_WAIT_BITSET`"); + } (timeout, ecx.read_scalar(bitset)?.to_u32()?) } else { - let [_, _, _, timeout] = - check_min_vararg_count("`syscall(SYS_futex, FUTEX_WAIT, ...)`", varargs)?; + let ([timeout], _) = + ecx.check_varargs(shim_varargs![*_], varargs, "syscall(SYS_futex, ...)")?; (timeout, u32::MAX) }; @@ -194,12 +198,19 @@ pub fn futex<'tcx>( let futex_ref = futex_ref.futex.clone(); let bitset = if op == futex_wake_bitset { - let [_, _, _, timeout, uaddr2, bitset] = check_min_vararg_count( - "`syscall(SYS_futex, FUTEX_WAKE_BITSET, ...)`", + let ([timeout, uaddr2, bitset], _) = ecx.check_varargs( + shim_varargs![*_, *_, u32], varargs, + "syscall(SYS_futex, ...)", )?; - let _timeout = ecx.read_pointer(timeout)?; - let _uaddr2 = ecx.read_pointer(uaddr2)?; + let timeout = ecx.read_pointer(timeout)?; + if !ecx.ptr_is_null(timeout)? { + throw_ub_format!("`timeout` pointer must be null for `FUTEX_WAKE_BITSET`"); + } + let uaddr2 = ecx.read_pointer(uaddr2)?; + if !ecx.ptr_is_null(uaddr2)? { + throw_ub_format!("`uaddr2` pointer must be null for `FUTEX_WAKE_BITSET`"); + } ecx.read_scalar(bitset)?.to_u32()? } else { u32::MAX diff --git a/src/tools/miri/src/shims/unix/linux_like/syscall.rs b/src/tools/miri/src/shims/unix/linux_like/syscall.rs index 875fd09428389..7dc036d8890b6 100644 --- a/src/tools/miri/src/shims/unix/linux_like/syscall.rs +++ b/src/tools/miri/src/shims/unix/linux_like/syscall.rs @@ -1,9 +1,7 @@ -use rustc_abi::CanonAbi; use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; -use crate::shims::sig::check_min_vararg_count; use crate::shims::unix::env::EvalContextExt; use crate::shims::unix::linux_like::eventfd::EvalContextExt as _; use crate::shims::unix::linux_like::sync::futex; @@ -17,7 +15,12 @@ pub fn syscall<'tcx>( args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx> { - let ([op], varargs) = ecx.check_shim_sig_variadic_lenient(abi, CanonAbi::C, link_name, args)?; + let ([op], varargs) = ecx.check_shim_sig_variadic( + shim_sig_variadic!(extern "C" fn(isize) -> isize), + link_name, + abi, + args, + )?; // The syscall variadic function is legal to call with more arguments than needed, // extra arguments are simply ignored. The important check is that when we use an // argument, we have to also check all arguments *before* it to ensure that they @@ -35,7 +38,11 @@ pub fn syscall<'tcx>( num if num == sys_getrandom => { // Used by getrandom 0.1 // The first argument is the syscall id, so skip over it. - let [ptr, len, flags] = check_min_vararg_count("syscall(SYS_getrandom, ...)", varargs)?; + let ([ptr, len, flags], _) = ecx.check_varargs( + shim_varargs![*_, usize, i32], + varargs, + "syscall(SYS_getrandom, ...)", + )?; let ptr = ecx.read_pointer(ptr)?; let len = ecx.read_target_usize(len)?; @@ -52,7 +59,8 @@ pub fn syscall<'tcx>( futex(ecx, varargs, dest)?; } num if num == sys_eventfd2 => { - let [initval, flags] = check_min_vararg_count("syscall(SYS_evetfd2, ...)", varargs)?; + let ([initval, flags], _) = + ecx.check_varargs(shim_varargs![u32, i32], varargs, "syscall(SYS_evetfd2, ...)")?; let result = ecx.eventfd(initval, flags)?; ecx.write_int(result.to_i32()?, dest)?; @@ -63,8 +71,11 @@ pub fn syscall<'tcx>( } num if num == sys_accept4 => { // Used on Android. - let [socket, address, address_len, flags] = - check_min_vararg_count("syscall(SYS_accept4, ...)", varargs)?; + let ([socket, address, address_len, flags], _) = ecx.check_varargs( + shim_varargs![i32, *_, *_, i32], + varargs, + "syscall(SYS_accept4, ...)", + )?; ecx.accept4(socket, address, address_len, Some(flags), dest)?; } num => { diff --git a/src/tools/miri/src/shims/unix/linux_like/thread.rs b/src/tools/miri/src/shims/unix/linux_like/thread.rs index ab15eeb1ea200..5555bc92b972a 100644 --- a/src/tools/miri/src/shims/unix/linux_like/thread.rs +++ b/src/tools/miri/src/shims/unix/linux_like/thread.rs @@ -1,9 +1,8 @@ -use rustc_abi::{CanonAbi, Size}; +use rustc_abi::Size; use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; -use crate::shims::sig::check_min_vararg_count; use crate::shims::unix::thread::{EvalContextExt as _, ThreadNameResult}; use crate::*; @@ -16,14 +15,21 @@ pub fn prctl<'tcx>( args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx> { - let ([op], varargs) = ecx.check_shim_sig_variadic_lenient(abi, CanonAbi::C, link_name, args)?; + let ([op], varargs) = ecx.check_shim_sig_variadic( + shim_sig_variadic!(extern "C" fn(i32) -> i32), + link_name, + abi, + args, + )?; let pr_set_name = ecx.eval_libc_i32("PR_SET_NAME"); let pr_get_name = ecx.eval_libc_i32("PR_GET_NAME"); let res = match ecx.read_scalar(op)?.to_i32()? { op if op == pr_set_name => { - let [name] = check_min_vararg_count("prctl(PR_SET_NAME, ...)", varargs)?; + let ([name], _) = + ecx.check_varargs(shim_varargs![*_], varargs, "prctl(PR_SET_NAME, ...)")?; + let name = ecx.read_scalar(name)?; let thread = ecx.pthread_self()?; // The Linux kernel silently truncates long names. @@ -34,7 +40,9 @@ pub fn prctl<'tcx>( Scalar::from_u32(0) } op if op == pr_get_name => { - let [name] = check_min_vararg_count("prctl(PR_GET_NAME, ...)", varargs)?; + let ([name], _) = + ecx.check_varargs(shim_varargs![*_], varargs, "prctl(PR_GET_NAME, ...)")?; + let name = ecx.read_scalar(name)?; let thread = ecx.pthread_self()?; let len = Scalar::from_target_usize(TASK_COMM_LEN, ecx); diff --git a/src/tools/miri/src/shims/unix/tcp_socket.rs b/src/tools/miri/src/shims/unix/tcp_socket.rs index 612f0a716de63..d0966fab8ab92 100644 --- a/src/tools/miri/src/shims/unix/tcp_socket.rs +++ b/src/tools/miri/src/shims/unix/tcp_socket.rs @@ -12,6 +12,7 @@ use rustc_middle::throw_unsup_format; use rustc_target::spec::Os; use crate::shims::files::{EvalContextExt as _, FdNum, FileDescription, FileDescriptionRef}; +use crate::shims::sig::Varargs; use crate::shims::unix::UnixFileDescription; use crate::shims::unix::socket::{SocketFamily, UnixSocketFileDescription}; use crate::*; @@ -185,7 +186,7 @@ impl UnixFileDescription for TcpSocket { fn ioctl<'tcx>( &self, op: Scalar, - arg: Option<&OpTy<'tcx>>, + args: Varargs<'tcx, '_>, ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx, i32> { assert!(ecx.machine.communicate(), "cannot have `TcpSocket` with isolation enabled!"); @@ -207,9 +208,7 @@ impl UnixFileDescription for TcpSocket { ); } - let Some(value_ptr) = arg else { - throw_ub_format!("ioctl: setting FIONBIO on sockets requires a third argument"); - }; + let ([value_ptr], _) = ecx.check_varargs(shim_varargs![*_], args, "ioctl")?; let value = ecx.deref_pointer_as(value_ptr, ecx.machine.layouts.i32)?; let non_block = ecx.read_scalar(&value)?.to_i32()? != 0; self.is_non_block.set(non_block); diff --git a/src/tools/miri/src/shims/unix/virtual_socket.rs b/src/tools/miri/src/shims/unix/virtual_socket.rs index 5f6b14fdfd44c..a035b56c1e323 100644 --- a/src/tools/miri/src/shims/unix/virtual_socket.rs +++ b/src/tools/miri/src/shims/unix/virtual_socket.rs @@ -14,6 +14,7 @@ use crate::shims::files::{ EvalContextExt as _, FileDescription, FileDescriptionRef, WeakFileDescriptionRef, }; use crate::shims::readiness::DelayedReadinessUpdates; +use crate::shims::sig::Varargs; use crate::shims::unix::UnixFileDescription; use crate::shims::unix::socket::UnixSocketFileDescription; use crate::*; @@ -260,7 +261,7 @@ impl UnixFileDescription for VirtualSocket { fn ioctl<'tcx>( &self, op: Scalar, - arg: Option<&OpTy<'tcx>>, + args: Varargs<'tcx, '_>, ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx, i32> { match self.fd_type { @@ -290,9 +291,7 @@ impl UnixFileDescription for VirtualSocket { ); } - let Some(value_ptr) = arg else { - throw_ub_format!("ioctl: setting FIONBIO on sockets requires a third argument"); - }; + let ([value_ptr], _) = ecx.check_varargs(shim_varargs![*_], args, "ioctl")?; let value = ecx.deref_pointer_as(value_ptr, ecx.machine.layouts.i32)?; let non_block = ecx.read_scalar(&value)?.to_i32()? != 0; self.is_nonblock.set(non_block); diff --git a/src/tools/miri/tests/fail/shims/non_vararg_signature_mismatch.rs b/src/tools/miri/tests/fail/shims/non_vararg_signature_mismatch.rs index ebbf0cc2bf331..bf3d4174dbdb7 100644 --- a/src/tools/miri/tests/fail/shims/non_vararg_signature_mismatch.rs +++ b/src/tools/miri/tests/fail/shims/non_vararg_signature_mismatch.rs @@ -15,6 +15,6 @@ fn main() { let c_path = CString::new(OsStr::new("./text").as_bytes()).expect("CString::new failed"); let _fd = unsafe { open(c_path.as_ptr(), /* value does not matter */ 0) - //~^ ERROR: calling a variadic function with a non-variadic caller-side signature + //~^ ERROR: is a variadic function, but the caller is using a non-variadic signature }; } diff --git a/src/tools/miri/tests/fail/shims/non_vararg_signature_mismatch.stderr b/src/tools/miri/tests/fail/shims/non_vararg_signature_mismatch.stderr index 510ffdf80cac4..788b499841174 100644 --- a/src/tools/miri/tests/fail/shims/non_vararg_signature_mismatch.stderr +++ b/src/tools/miri/tests/fail/shims/non_vararg_signature_mismatch.stderr @@ -1,4 +1,4 @@ -error: Undefined Behavior: calling a variadic function with a non-variadic caller-side signature +error: Undefined Behavior: ABI mismatch: `open` is a variadic function, but the caller is using a non-variadic signature --> tests/fail/shims/non_vararg_signature_mismatch.rs:LL:CC | LL | open(c_path.as_ptr(), /* value does not matter */ 0) diff --git a/src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.rs b/src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.rs index 5453db57bbd8f..34f6ae24f3e1d 100644 --- a/src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.rs +++ b/src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.rs @@ -14,6 +14,6 @@ fn main() { let c_path = CString::new(OsStr::new("./text").as_bytes()).expect("CString::new failed"); let _fd = unsafe { open(c_path.as_ptr(), /* value does not matter */ 0) - //~^ ERROR: incorrect number of fixed arguments for variadic function + //~^ ERROR: takes 2 fixed (non-variadic) arguments, but 1 argument was given }; } diff --git a/src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.stderr b/src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.stderr index 2442f051c81cc..5ded58247fd37 100644 --- a/src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.stderr +++ b/src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.stderr @@ -1,4 +1,4 @@ -error: Undefined Behavior: incorrect number of fixed arguments for variadic function `open`: got 1, expected 2 +error: Undefined Behavior: ABI mismatch: calling `open` which takes 2 fixed (non-variadic) arguments, but 1 argument was given --> tests/fail/shims/wrong_fixed_arg_count.rs:LL:CC | LL | open(c_path.as_ptr(), /* value does not matter */ 0) From 2ef83c25188f4b6e162a355e3fc8b92d5066881d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 23 Aug 2026 20:08:31 +0200 Subject: [PATCH 09/54] check_sim_sig: package arguments in tuple so they all go on the same line --- src/tools/miri/src/shims/alloc.rs | 12 +- src/tools/miri/src/shims/backtrace.rs | 10 +- src/tools/miri/src/shims/foreign_items.rs | 134 ++--- src/tools/miri/src/shims/sig.rs | 10 +- .../src/shims/unix/android/foreign_items.rs | 16 +- .../miri/src/shims/unix/foreign_items.rs | 510 ++++++------------ .../src/shims/unix/freebsd/foreign_items.rs | 4 +- .../src/shims/unix/linux/foreign_items.rs | 36 +- .../miri/src/shims/unix/linux_like/syscall.rs | 4 +- .../miri/src/shims/unix/linux_like/thread.rs | 4 +- .../src/shims/unix/netbsd/foreign_items.rs | 6 +- .../src/shims/unix/solarish/foreign_items.rs | 20 +- .../miri/src/shims/windows/foreign_items.rs | 300 +++-------- 13 files changed, 305 insertions(+), 761 deletions(-) diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs index fe0a351d635ba..135a2914c8fc8 100644 --- a/src/tools/miri/src/shims/alloc.rs +++ b/src/tools/miri/src/shims/alloc.rs @@ -125,9 +125,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { SpecialAllocatorMethod::Alloc | SpecialAllocatorMethod::AllocZeroed => { let [size, align] = this.check_shim_sig( shim_sig_nounwind!(extern "Rust" fn(usize, core::mem::Alignment) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; let size = this.read_target_usize(size)?; let align = this.read_target_usize(align)?; @@ -150,9 +148,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { SpecialAllocatorMethod::Dealloc => { let [ptr, old_size, align] = this.check_shim_sig( shim_sig_nounwind!(extern "Rust" fn(*_, usize, core::mem::Alignment) -> ()), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr = this.read_pointer(ptr)?; let old_size = this.read_target_usize(old_size)?; @@ -168,9 +164,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { SpecialAllocatorMethod::Realloc => { let [ptr, old_size, align, new_size] = this.check_shim_sig( shim_sig_nounwind!(extern "Rust" fn(*_, usize, core::mem::Alignment, usize) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr = this.read_pointer(ptr)?; let old_size = this.read_target_usize(old_size)?; diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs index 7b66ce563f646..923a8dedc0591 100644 --- a/src/tools/miri/src/shims/backtrace.rs +++ b/src/tools/miri/src/shims/backtrace.rs @@ -16,7 +16,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); let [flags] = - this.check_shim_sig(shim_sig!(extern "Rust" fn(u64) -> usize), link_name, abi, args)?; + this.check_shim_sig(shim_sig!(extern "Rust" fn(u64) -> usize), (link_name, abi, args))?; let flags = this.read_scalar(flags)?.to_u64()?; if flags != 0 { @@ -38,8 +38,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let ptr_ty = this.machine.layouts.mut_raw_ptr.ty; let ptr_layout = this.layout_of(ptr_ty)?; - let [flags, buf] = - this.check_shim_sig(shim_sig!(extern "Rust" fn(u64, *_) -> ()), link_name, abi, args)?; + let [flags, buf] = this + .check_shim_sig(shim_sig!(extern "Rust" fn(u64, *_) -> ()), (link_name, abi, args))?; let flags = this.read_scalar(flags)?.to_u64()?; let buf_place = this.deref_pointer_as(buf, ptr_layout)?; @@ -195,9 +195,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let [ptr, flags, name_ptr, filename_ptr] = this.check_shim_sig( shim_sig!(extern "Rust" fn(*_, u64, *_, *_) -> ()), - link_name, - abi, - args, + (link_name, abi, args), )?; let flags = this.read_scalar(flags)?.to_u64()?; diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index df87fb5322982..ac47fbe6d7b38 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -319,9 +319,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // instantly stable. let [] = this.check_shim_sig( shim_sig_nounwind!(extern "Rust" fn() -> ()), - link_name, - abi, - args, + (link_name, abi, args), )?; } @@ -329,9 +327,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "miri_alloc" => { let [size, align] = this.check_shim_sig( shim_sig!(extern "Rust" fn(usize, usize) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; let size = this.read_target_usize(size)?; let align = this.read_target_usize(align)?; @@ -350,9 +346,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "miri_dealloc" => { let [ptr, old_size, align] = this.check_shim_sig( shim_sig!(extern "Rust" fn(*_, usize, usize) -> ()), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr = this.read_pointer(ptr)?; let old_size = this.read_target_usize(old_size)?; @@ -368,9 +362,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "miri_track_alloc" => { let [ptr] = this.check_shim_sig( shim_sig!(extern "Rust" fn(*_) -> ()), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr = this.read_pointer(ptr)?; let (alloc_id, _, _) = this.ptr_get_alloc_id(ptr, 0).map_err_kind(|_e| { @@ -386,26 +378,20 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "miri_start_unwind" => { - let [payload] = this.check_shim_sig( - shim_sig!(extern "Rust" fn(*_) -> !), - link_name, - abi, - args, - )?; + let [payload] = this + .check_shim_sig(shim_sig!(extern "Rust" fn(*_) -> !), (link_name, abi, args))?; this.handle_miri_start_unwind(payload)?; return interp_ok(EmulateItemResult::NeedsUnwind); } "miri_run_provenance_gc" => { - let [] = - this.check_shim_sig(shim_sig!(extern "Rust" fn() -> ()), link_name, abi, args)?; + let [] = this + .check_shim_sig(shim_sig!(extern "Rust" fn() -> ()), (link_name, abi, args))?; this.run_provenance_gc(); } "miri_get_alloc_id" => { let [ptr] = this.check_shim_sig( shim_sig!(extern "Rust" fn(*_) -> u64), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr = this.read_pointer(ptr)?; let (alloc_id, _, _) = this.ptr_get_alloc_id(ptr, 0).map_err_kind(|_e| { @@ -418,9 +404,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "miri_print_borrow_state" => { let [id, show_unnamed] = this.check_shim_sig( shim_sig!(extern "Rust" fn(u64, bool) -> ()), - link_name, - abi, - args, + (link_name, abi, args), )?; let id = this.read_scalar(id)?.to_u64()?; let show_unnamed = this.read_scalar(show_unnamed)?.to_bool()?; @@ -437,9 +421,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // tests more strict. let [ptr, nth_parent, name] = this.check_shim_sig( shim_sig!(extern "Rust" fn(*_, u8, &[u8]) -> ()), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr = this.read_pointer(ptr)?; let nth_parent = this.read_scalar(nth_parent)?.to_u8()?; @@ -455,9 +437,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "miri_static_root" => { let [ptr] = this.check_shim_sig( shim_sig!(extern "Rust" fn(*_) -> ()), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr = this.read_pointer(ptr)?; let (alloc_id, offset, _) = this.ptr_get_alloc_id(ptr, 0)?; @@ -471,9 +451,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "miri_host_to_target_path" => { let [ptr, out, out_size] = this.check_shim_sig( shim_sig!(extern "Rust" fn(*_, *_, usize) -> usize), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr = this.read_pointer(ptr)?; let out = this.read_pointer(out)?; @@ -493,9 +471,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { let [start_routine, func_arg] = this.check_shim_sig( // FIXME: The first argument is actually a function pointer. shim_sig!(extern "Rust" fn(fn(..) -> _, *_) -> usize), - link_name, - abi, - args, + (link_name, abi, args), )?; let start_routine = this.read_pointer(start_routine)?; let func_arg = this.read_immediate(func_arg)?; @@ -511,9 +487,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "miri_thread_join" => { let [thread_id] = this.check_shim_sig( shim_sig!(extern "Rust" fn(usize) -> bool), - link_name, - abi, - args, + (link_name, abi, args), )?; let thread = this.read_target_usize(thread_id)?; @@ -535,8 +509,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Hint that a loop is spinning indefinitely. "miri_spin_loop" => { - let [] = - this.check_shim_sig(shim_sig!(extern "Rust" fn() -> ()), link_name, abi, args)?; + let [] = this + .check_shim_sig(shim_sig!(extern "Rust" fn() -> ()), (link_name, abi, args))?; // Try to run another thread to maximize the chance of finding actual bugs. this.yield_active_thread(); @@ -563,9 +537,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "miri_write_to_stdout" | "miri_write_to_stderr" => { let [msg] = this.check_shim_sig( shim_sig!(extern "Rust" fn(&[u8]) -> ()), - link_name, - abi, - args, + (link_name, abi, args), )?; let msg = this.read_immediate(msg)?; let msg = this.read_byte_slice(&msg)?; @@ -582,9 +554,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { let [ptr, align] = this.check_shim_sig( shim_sig!(extern "Rust" fn(*_, usize) -> ()), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr = this.read_pointer(ptr)?; @@ -628,9 +598,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "miri_genmc_assume" => { let [condition] = this.check_shim_sig( shim_sig!(extern "Rust" fn(bool) -> ()), - link_name, - abi, - args, + (link_name, abi, args), )?; if this.machine.data_race.as_genmc_ref().is_some() { @@ -643,8 +611,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Aborting the process. "exit" => { // FIXME: This does not have a direct test (#3179). - let [code] = - this.check_shim_sig(shim_sig!(extern "C" fn(i32) -> ()), link_name, abi, args)?; + let [code] = this + .check_shim_sig(shim_sig!(extern "C" fn(i32) -> ()), (link_name, abi, args))?; let code = this.read_scalar(code)?.to_i32()?; if let Some(genmc_ctx) = this.machine.data_race.as_genmc_ref() { // If there is no error, execution should continue (on a different thread). @@ -660,7 +628,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "abort" => { // FIXME: This does not have a direct test (#3179). let [] = - this.check_shim_sig(shim_sig!(extern "C" fn() -> ()), link_name, abi, args)?; + this.check_shim_sig(shim_sig!(extern "C" fn() -> ()), (link_name, abi, args))?; throw_machine_stop!(TerminationInfo::Abort( "the program aborted execution".to_owned() )); @@ -670,9 +638,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "malloc" => { let [size] = this.check_shim_sig( shim_sig!(extern "C" fn(usize) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; let size = this.read_target_usize(size)?; if size <= this.max_size_of_val().bytes() { @@ -689,9 +655,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "calloc" => { let [items, elem_size] = this.check_shim_sig( shim_sig!(extern "C" fn(usize, usize) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; let items = this.read_target_usize(items)?; let elem_size = this.read_target_usize(elem_size)?; @@ -707,17 +671,15 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "free" => { - let [ptr] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> ()), link_name, abi, args)?; + let [ptr] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> ()), (link_name, abi, args))?; let ptr = this.read_pointer(ptr)?; this.free(ptr)?; } "realloc" => { let [old_ptr, new_size] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, usize) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; let old_ptr = this.read_pointer(old_ptr)?; let new_size = this.read_target_usize(new_size)?; @@ -737,9 +699,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { let [ptr] = this.check_shim_sig( shim_sig!(extern "C" fn(*_) -> usize), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr = this.read_pointer(ptr)?; let size = if this.ptr_is_null(ptr)? { @@ -770,9 +730,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "memcmp" => { let [left, right, n] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, *_, usize) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let left = this.read_pointer(left)?; let right = this.read_pointer(right)?; @@ -803,9 +761,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "memchr" => { let [ptr, val, num] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, i32, usize) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr = this.read_pointer(ptr)?; let val = this.read_scalar(val)?.to_i32()?; @@ -832,9 +788,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { let [ptr, val, num] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, i32, usize) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr = this.read_pointer(ptr)?; let val = this.read_scalar(val)?.to_i32()?; @@ -858,9 +812,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "strlen" => { let [ptr] = this.check_shim_sig( shim_sig!(extern "C" fn(*_) -> usize), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr = this.read_pointer(ptr)?; // This reads at least 1 byte, so we are already enforcing that this is a valid pointer. @@ -873,9 +825,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "strnlen" => { let [ptr, num] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, usize) -> usize), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr = this.read_pointer(ptr)?; let num = this.read_target_usize(num)?; @@ -891,9 +841,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "wcslen" => { let [ptr] = this.check_shim_sig( shim_sig!(extern "C" fn(*_) -> usize), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr = this.read_pointer(ptr)?; // This reads at least 1 byte, so we are already enforcing that this is a valid pointer. @@ -906,9 +854,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "memcpy" => { let [ptr_dest, ptr_src, n] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, *_, usize) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr_dest = this.read_pointer(ptr_dest)?; let ptr_src = this.read_pointer(ptr_src)?; @@ -925,9 +871,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "strcpy" => { let [ptr_dest, ptr_src] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, *_) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr_dest = this.read_pointer(ptr_dest)?; let ptr_src = this.read_pointer(ptr_src)?; @@ -945,9 +889,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "memset" => { let [ptr_dest, val, n] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, i32, usize) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr_dest = this.read_pointer(ptr_dest)?; let val = this.read_scalar(val)?.to_i32()?; diff --git a/src/tools/miri/src/shims/sig.rs b/src/tools/miri/src/shims/sig.rs index e044ed09db8a6..0a0f84eadadec 100644 --- a/src/tools/miri/src/shims/sig.rs +++ b/src/tools/miri/src/shims/sig.rs @@ -340,9 +340,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn check_shim_sig<'a, const N: usize>( &self, shim_sig: fn(&MiriInterpCx<'tcx>) -> ShimSig<'tcx, N>, - link_name: Symbol, - caller_fn_abi: &FnAbi<'tcx, Ty<'tcx>>, - caller_args: &'a [OpTy<'tcx>], + // We take these as a tuple so that this takes less space on the caller side. + (link_name, caller_fn_abi, caller_args): (Symbol, &FnAbi<'tcx, Ty<'tcx>>, &'a [OpTy<'tcx>]), ) -> InterpResult<'tcx, &'a [OpTy<'tcx>; N]> { let this = self.eval_context_ref(); @@ -367,9 +366,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn check_shim_sig_variadic<'a, const N: usize>( &self, shim_sig: fn(&MiriInterpCx<'tcx>) -> ShimSig<'tcx, N>, - link_name: Symbol, - caller_fn_abi: &FnAbi<'tcx, Ty<'tcx>>, - caller_args: &'a [OpTy<'tcx>], + // We take these as a tuple so that this takes less space on the caller side. + (link_name, caller_fn_abi, caller_args): (Symbol, &FnAbi<'tcx, Ty<'tcx>>, &'a [OpTy<'tcx>]), ) -> InterpResult<'tcx, (&'a [OpTy<'tcx>; N], Varargs<'tcx, 'a>)> { let this = self.eval_context_ref(); diff --git a/src/tools/miri/src/shims/unix/android/foreign_items.rs b/src/tools/miri/src/shims/unix/android/foreign_items.rs index 37f789362cc81..fea689f63152c 100644 --- a/src/tools/miri/src/shims/unix/android/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/android/foreign_items.rs @@ -31,9 +31,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [fd, buf, count, offset] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, usize, libc::off64_t) -> isize), - link_name, - abi, - args, + (link_name, abi, args), )?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; @@ -45,9 +43,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [fd, buf, n, offset] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, usize, libc::off64_t) -> isize), - link_name, - abi, - args, + (link_name, abi, args), )?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; @@ -60,9 +56,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [fd, offset, whence] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, libc::off64_t, i32) -> libc::off64_t), - link_name, - abi, - args, + (link_name, abi, args), )?; let fd = this.read_scalar(fd)?.to_i32()?; let offset = this.read_scalar(offset)?.to_int(offset.layout.size)?; @@ -72,9 +66,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "ftruncate64" => { let [fd, length] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, libc::off64_t) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let fd = this.read_scalar(fd)?.to_i32()?; let length = this.read_scalar(length)?.to_int(length.layout.size)?; diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index e96b73bbf7247..f8d0641e42db5 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -131,23 +131,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // Environment related shims "getenv" => { - let [name] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> *_), link_name, abi, args)?; + let [name] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> *_), (link_name, abi, args))?; let result = this.getenv(name)?; this.write_pointer(result, dest)?; } "unsetenv" => { - let [name] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [name] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; let result = this.unsetenv(name)?; this.write_scalar(result, dest)?; } "setenv" => { let [name, value, overwrite] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, *_, i32) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; this.read_scalar(overwrite)?.to_i32()?; let result = this.setenv(name, value)?; @@ -157,9 +155,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [buf, size] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, usize) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.getcwd(buf, size)?; this.write_pointer(result, dest)?; @@ -167,26 +163,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "gethostname" => { let [name, len] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, usize) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.gethostname(name, len)?; this.write_scalar(result, dest)?; } "chdir" => { // FIXME: This does not have a direct test (#3179). - let [path] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [path] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; let result = this.chdir(path)?; this.write_scalar(result, dest)?; } "getpid" => { let [] = this.check_shim_sig( shim_sig!(extern "C" fn() -> libc::pid_t), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.getpid()?; this.write_scalar(result, dest)?; @@ -198,17 +190,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { link_name, )?; - let [uname] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [uname] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; let result = this.uname(uname, None)?; this.write_scalar(result, dest)?; } "sysconf" => { let [val] = this.check_shim_sig( shim_sig!(extern "C" fn(i32) -> isize), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.sysconf(val)?; this.write_scalar(result, dest)?; @@ -217,9 +207,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "read" => { let [fd, buf, count] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, usize) -> isize), - link_name, - abi, - args, + (link_name, abi, args), )?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; @@ -229,9 +217,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "write" => { let [fd, buf, n] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, usize) -> isize), - link_name, - abi, - args, + (link_name, abi, args), )?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; @@ -242,27 +228,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "readv" => { let [fd, iov, iovcnt] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, i32) -> isize), - link_name, - abi, - args, + (link_name, abi, args), )?; this.readv(fd, iov, iovcnt, None, dest)?; } "writev" => { let [fd, iov, iovcnt] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, i32) -> isize), - link_name, - abi, - args, + (link_name, abi, args), )?; this.writev(fd, iov, iovcnt, None, dest)?; } "pread" => { let [fd, buf, count, offset] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, usize, libc::off_t) -> isize), - link_name, - abi, - args, + (link_name, abi, args), )?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; @@ -273,9 +253,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "pwrite" => { let [fd, buf, n, offset] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, usize, libc::off_t) -> isize), - link_name, - abi, - args, + (link_name, abi, args), )?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; @@ -287,29 +265,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "preadv" => { let [fd, iov, iovcnt, offset] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, i32, libc::off_t) -> isize), - link_name, - abi, - args, + (link_name, abi, args), )?; this.readv(fd, iov, iovcnt, Some(offset), dest)?; } "pwritev" => { let [fd, iov, iovcnt, offset] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, i32, libc::off_t) -> isize), - link_name, - abi, - args, + (link_name, abi, args), )?; this.writev(fd, iov, iovcnt, Some(offset), dest)?; } "close" => { - let [fd] = this.check_shim_sig( - shim_sig!(extern "C" fn(i32) -> i32), - link_name, - abi, - args, - )?; + let [fd] = this + .check_shim_sig(shim_sig!(extern "C" fn(i32) -> i32), (link_name, abi, args))?; let fd = this.read_scalar(fd)?.to_i32()?; let result = this.close(fd)?; this.write_scalar(result, dest)?; @@ -317,20 +287,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "fcntl" => { let ([fd_num, cmd], varargs) = this.check_shim_sig_variadic( shim_sig_variadic!(extern "C" fn(i32, i32) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.fcntl(fd_num, cmd, varargs)?; this.write_scalar(result, dest)?; } "dup" => { - let [old_fd] = this.check_shim_sig( - shim_sig!(extern "C" fn(i32) -> i32), - link_name, - abi, - args, - )?; + let [old_fd] = this + .check_shim_sig(shim_sig!(extern "C" fn(i32) -> i32), (link_name, abi, args))?; let old_fd = this.read_scalar(old_fd)?.to_i32()?; let new_fd = this.dup(old_fd)?; this.write_scalar(new_fd, dest)?; @@ -338,9 +302,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "dup2" => { let [old_fd, new_fd] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, i32) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let old_fd = this.read_scalar(old_fd)?.to_i32()?; let new_fd = this.read_scalar(new_fd)?.to_i32()?; @@ -356,9 +318,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let [fd, op] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, i32) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let fd = this.read_scalar(fd)?.to_i32()?; let op = this.read_scalar(op)?.to_i32()?; @@ -379,9 +339,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } else { shim_sig_variadic!(extern "C" fn(i32, i32) -> i32) }, - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.ioctl(fd, op, varargs)?; this.write_scalar(result, dest)?; @@ -393,17 +351,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // has O_CREAT (or on linux O_TMPFILE, but miri doesn't support that) set let ([path_raw, flag], varargs) = this.check_shim_sig_variadic( shim_sig_variadic!(extern "C" fn(*_, i32) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.open(path_raw, flag, varargs)?; this.write_scalar(result, dest)?; } "unlink" => { // FIXME: This does not have a direct test (#3179). - let [path] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [path] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; let result = this.unlink(path)?; this.write_scalar(result, dest)?; } @@ -411,9 +367,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [target, linkpath] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.symlink(target, linkpath)?; this.write_scalar(result, dest)?; @@ -421,9 +375,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "linkat" => { let [oldfd, oldpath, newfd, newpath, flags] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, i32, *_, i32) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.linkat(oldfd, oldpath, newfd, newpath, flags)?; this.write_scalar(result, dest)?; @@ -431,9 +383,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "fstat" => { let [fd, buf] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.fstat(fd, buf)?; this.write_scalar(result, dest)?; @@ -441,9 +391,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "lstat" => { let [path, buf] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.lstat(path, buf)?; this.write_scalar(result, dest)?; @@ -451,9 +399,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "stat" => { let [path, buf] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.stat(path, buf)?; this.write_scalar(result, dest)?; @@ -461,9 +407,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "chmod" => { let [path, mode] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, libc::mode_t) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.chmod(path, mode)?; this.write_scalar(result, dest)?; @@ -471,9 +415,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "fchmod" => { let [fd, mode] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, libc::mode_t) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.fchmod(fd, mode)?; this.write_scalar(result, dest)?; @@ -482,9 +424,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [oldpath, newpath] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.rename(oldpath, newpath)?; this.write_scalar(result, dest)?; @@ -493,44 +433,40 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [path, mode] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, libc::mode_t) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.mkdir(path, mode)?; this.write_scalar(result, dest)?; } "rmdir" => { // FIXME: This does not have a direct test (#3179). - let [path] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [path] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; let result = this.rmdir(path)?; this.write_scalar(result, dest)?; } "opendir" => { - let [name] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> *_), link_name, abi, args)?; + let [name] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> *_), (link_name, abi, args))?; let result = this.opendir(name)?; this.write_scalar(result, dest)?; } "closedir" => { - let [dirp] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [dirp] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; let result = this.closedir(dirp)?; this.write_scalar(result, dest)?; } "readdir" => { - let [dirp] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> *_), link_name, abi, args)?; + let [dirp] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> *_), (link_name, abi, args))?; this.readdir(dirp, dest)?; } "lseek" => { // FIXME: This does not have a direct test (#3179). let [fd, offset, whence] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, libc::off_t, i32) -> libc::off_t), - link_name, - abi, - args, + (link_name, abi, args), )?; let fd = this.read_scalar(fd)?.to_i32()?; let offset = this.read_scalar(offset)?.to_int(offset.layout.size)?; @@ -540,9 +476,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "ftruncate" => { let [fd, length] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, libc::off_t) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let fd = this.read_scalar(fd)?.to_i32()?; let length = this.read_scalar(length)?.to_int(length.layout.size)?; @@ -551,32 +485,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "fsync" => { // FIXME: This does not have a direct test (#3179). - let [fd] = this.check_shim_sig( - shim_sig!(extern "C" fn(i32) -> i32), - link_name, - abi, - args, - )?; + let [fd] = this + .check_shim_sig(shim_sig!(extern "C" fn(i32) -> i32), (link_name, abi, args))?; let result = this.fsync(fd)?; this.write_scalar(result, dest)?; } "fdatasync" => { // FIXME: This does not have a direct test (#3179). - let [fd] = this.check_shim_sig( - shim_sig!(extern "C" fn(i32) -> i32), - link_name, - abi, - args, - )?; + let [fd] = this + .check_shim_sig(shim_sig!(extern "C" fn(i32) -> i32), (link_name, abi, args))?; let result = this.fdatasync(fd)?; this.write_scalar(result, dest)?; } "futimens" => { let [fd, times] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.futimens(fd, times)?; this.write_scalar(result, dest)?; @@ -584,9 +508,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "readlink" => { let [pathname, buf, bufsize] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, *_, usize) -> isize), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.readlink(pathname, buf, bufsize)?; this.write_scalar(Scalar::from_target_isize(result, this), dest)?; @@ -594,9 +516,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "posix_fadvise" => { let [fd, offset, len, advice] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, libc::off_t, libc::off_t, i32) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; this.read_scalar(fd)?.to_i32()?; this.read_scalar(offset)?.to_int(offset.layout.size)?; @@ -615,9 +535,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let [fd, offset, len] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, libc::off_t, libc::off_t) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let fd = this.read_scalar(fd)?.to_i32()?; @@ -633,16 +551,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "realpath" => { let [path, resolved_path] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, *_) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.realpath(path, resolved_path)?; this.write_scalar(result, dest)?; } "mkstemp" => { - let [template] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [template] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; let result = this.mkstemp(template)?; this.write_scalar(result, dest)?; } @@ -651,9 +567,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "poll" => { let [fds, nfds, timeout] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, libc::nfds_t, i32) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; this.poll(fds, nfds, timeout, dest)?; } @@ -662,16 +576,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "socketpair" => { let [domain, type_, protocol, sv] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, i32, i32, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.socketpair(domain, type_, protocol, sv)?; this.write_scalar(result, dest)?; } "pipe" => { - let [pipefd] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [pipefd] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; let result = this.pipe2(pipefd, /*flags*/ None)?; this.write_scalar(result, dest)?; } @@ -684,9 +596,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let [pipefd, flags] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, i32) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.pipe2(pipefd, Some(flags))?; this.write_scalar(result, dest)?; @@ -696,9 +606,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "socket" => { let [domain, type_, protocol] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, i32, i32) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.socket(domain, type_, protocol)?; this.write_scalar(result, dest)?; @@ -706,9 +614,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "bind" => { let [socket, address, address_len] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, libc::socklen_t) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.bind(socket, address, address_len)?; this.write_scalar(result, dest)?; @@ -716,9 +622,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "listen" => { let [socket, backlog] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, i32) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.listen(socket, backlog)?; this.write_scalar(result, dest)?; @@ -726,54 +630,42 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "accept" => { let [socket, address, address_len] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; this.accept4(socket, address, address_len, /* flags */ None, dest)?; } "accept4" => { let [socket, address, address_len, flags] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, *_, i32) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; this.accept4(socket, address, address_len, Some(flags), dest)?; } "connect" => { let [socket, address, address_len] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, libc::socklen_t) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; this.connect(socket, address, address_len, dest)?; } "send" => { let [socket, buffer, length, flags] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, libc::size_t, i32) -> libc::ssize_t), - link_name, - abi, - args, + (link_name, abi, args), )?; this.send(socket, buffer, length, flags, dest)?; } "recv" => { let [socket, buffer, length, flags] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, libc::size_t, i32) -> libc::ssize_t), - link_name, - abi, - args, + (link_name, abi, args), )?; this.recv(socket, buffer, length, flags, dest)?; } "setsockopt" => { let [socket, level, option_name, option_value, option_len] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, i32, i32, *_, libc::socklen_t) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.setsockopt(socket, level, option_name, option_value, option_len)?; @@ -782,9 +674,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "getsockopt" => { let [socket, level, option_name, option_value, option_len] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, i32, i32, *_, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.getsockopt(socket, level, option_name, option_value, option_len)?; @@ -793,9 +683,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "getsockname" => { let [socket, address, address_len] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.getsockname(socket, address, address_len)?; this.write_scalar(result, dest)?; @@ -803,18 +691,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "getpeername" => { let [socket, address, address_len] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; this.getpeername(socket, address, address_len, dest)?; } "shutdown" => { let [sockfd, how] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, i32) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.shutdown(sockfd, how)?; this.write_scalar(result, dest)?; @@ -822,16 +706,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "getaddrinfo" => { let [node, service, hints, res] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, *_, *_, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.getaddrinfo(node, service, hints, res)?; this.write_scalar(result, dest)?; } "freeaddrinfo" => { - let [res] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> ()), link_name, abi, args)?; + let [res] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> ()), (link_name, abi, args))?; this.freeaddrinfo(res)?; } @@ -839,9 +721,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "gettimeofday" => { let [tv, tz] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.gettimeofday(tv, tz)?; this.write_scalar(result, dest)?; @@ -849,9 +729,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "localtime_r" => { let [timep, result_op] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, *_) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.localtime_r(timep, result_op)?; this.write_pointer(result, dest)?; @@ -859,9 +737,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "clock_gettime" => { let [clk_id, tp] = this.check_shim_sig( shim_sig!(extern "C" fn(libc::clockid_t, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; this.clock_gettime(clk_id, tp, dest)?; } @@ -870,9 +746,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "posix_memalign" => { let [memptr, align, size] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, usize, usize) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.posix_memalign(memptr, align, size)?; this.write_scalar(result, dest)?; @@ -881,9 +755,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "mmap" => { let [addr, length, prot, flags, fd, offset] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, usize, i32, i32, i32, libc::off_t) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?; let ptr = this.mmap(addr, length, prot, flags, fd, offset)?; @@ -892,9 +764,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "munmap" => { let [addr, length] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, usize) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.munmap(addr, length)?; this.write_scalar(result, dest)?; @@ -902,9 +772,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "mprotect" => { let [addr, length, prot] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, usize, i32) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.mprotect(addr, length, prot)?; this.write_scalar(result, dest)?; @@ -912,9 +780,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "madvise" => { let [addr, length, advice] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, usize, i32) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.madvise(addr, length, advice)?; this.write_scalar(result, dest)?; @@ -926,9 +792,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let [ptr, nmemb, size] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, usize, usize) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr = this.read_pointer(ptr)?; let nmemb = this.read_target_usize(nmemb)?; @@ -954,9 +818,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // (MSVC explicitly does not support this.) let [align, size] = this.check_shim_sig( shim_sig!(extern "C" fn(usize, usize) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; let res = this.aligned_alloc(align, size)?; this.write_pointer(res, dest)?; @@ -966,9 +828,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "dlsym" => { let [handle, symbol] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, *_) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; this.read_target_usize(handle)?; let symbol = this.read_pointer(symbol)?; @@ -990,9 +850,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "pthread_key_create" => { let [key, dtor] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, fn(..) -> _) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let key_place = this.deref_pointer_as(key, this.libc_ty_layout("pthread_key_t"))?; let dtor = this.read_pointer(dtor)?; @@ -1027,9 +885,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [key] = this.check_shim_sig( shim_sig!(extern "C" fn(libc::pthread_key_t) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let key = this.read_scalar(key)?.to_bits(key.layout.size)?; this.machine.tls.delete_tls_key(key)?; @@ -1040,9 +896,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [key] = this.check_shim_sig( shim_sig!(extern "C" fn(libc::pthread_key_t) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; let key = this.read_scalar(key)?.to_bits(key.layout.size)?; let active_thread = this.active_thread(); @@ -1052,9 +906,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "pthread_setspecific" => { let [key, new_ptr] = this.check_shim_sig( shim_sig!(extern "C" fn(libc::pthread_key_t, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let key = this.read_scalar(key)?.to_bits(key.layout.size)?; let active_thread = this.active_thread(); @@ -1067,106 +919,100 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Synchronization primitives "pthread_mutexattr_init" => { - let [attr] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [attr] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; this.pthread_mutexattr_init(attr)?; this.write_null(dest)?; } "pthread_mutexattr_settype" => { let [attr, kind] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, i32) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.pthread_mutexattr_settype(attr, kind)?; this.write_scalar(result, dest)?; } "pthread_mutexattr_destroy" => { - let [attr] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [attr] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; this.pthread_mutexattr_destroy(attr)?; this.write_null(dest)?; } "pthread_mutex_init" => { let [mutex, attr] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; this.pthread_mutex_init(mutex, attr)?; this.write_null(dest)?; } "pthread_mutex_lock" => { - let [mutex] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [mutex] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; this.pthread_mutex_lock(mutex, dest)?; } "pthread_mutex_trylock" => { - let [mutex] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [mutex] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; let result = this.pthread_mutex_trylock(mutex)?; this.write_scalar(result, dest)?; } "pthread_mutex_unlock" => { - let [mutex] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [mutex] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; let result = this.pthread_mutex_unlock(mutex)?; this.write_scalar(result, dest)?; } "pthread_mutex_destroy" => { - let [mutex] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [mutex] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; this.pthread_mutex_destroy(mutex)?; this.write_int(0, dest)?; } "pthread_rwlock_rdlock" => { - let [rwlock] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [rwlock] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; this.pthread_rwlock_rdlock(rwlock, dest)?; } "pthread_rwlock_tryrdlock" => { - let [rwlock] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [rwlock] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; let result = this.pthread_rwlock_tryrdlock(rwlock)?; this.write_scalar(result, dest)?; } "pthread_rwlock_wrlock" => { - let [rwlock] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [rwlock] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; this.pthread_rwlock_wrlock(rwlock, dest)?; } "pthread_rwlock_trywrlock" => { - let [rwlock] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [rwlock] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; let result = this.pthread_rwlock_trywrlock(rwlock)?; this.write_scalar(result, dest)?; } "pthread_rwlock_unlock" => { - let [rwlock] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [rwlock] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; this.pthread_rwlock_unlock(rwlock)?; this.write_null(dest)?; } "pthread_rwlock_destroy" => { - let [rwlock] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [rwlock] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; this.pthread_rwlock_destroy(rwlock)?; this.write_null(dest)?; } "pthread_condattr_init" => { - let [attr] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [attr] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; this.pthread_condattr_init(attr)?; this.write_null(dest)?; } "pthread_condattr_setclock" => { let [attr, clock_id] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, i32) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.pthread_condattr_setclock(attr, clock_id)?; this.write_scalar(result, dest)?; @@ -1174,64 +1020,56 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "pthread_condattr_getclock" => { let [attr, clock_id] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; this.pthread_condattr_getclock(attr, clock_id)?; this.write_null(dest)?; } "pthread_condattr_destroy" => { - let [attr] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [attr] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; this.pthread_condattr_destroy(attr)?; this.write_null(dest)?; } "pthread_cond_init" => { let [cond, attr] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; this.pthread_cond_init(cond, attr)?; this.write_null(dest)?; } "pthread_cond_signal" => { - let [cond] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [cond] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; this.pthread_cond_signal(cond)?; this.write_null(dest)?; } "pthread_cond_broadcast" => { - let [cond] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [cond] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; this.pthread_cond_broadcast(cond)?; this.write_null(dest)?; } "pthread_cond_wait" => { let [cond, mutex] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; this.pthread_cond_wait(cond, mutex, dest)?; } "pthread_cond_timedwait" => { let [cond, mutex, abstime] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, *_, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; this.pthread_cond_timedwait( cond, mutex, abstime, dest, /* macos_relative_np */ false, )?; } "pthread_cond_destroy" => { - let [cond] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [cond] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; this.pthread_cond_destroy(cond)?; this.write_null(dest)?; } @@ -1240,9 +1078,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "pthread_create" => { let [thread, attr, start, arg] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, *_, fn(..) -> _, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; this.pthread_create(thread, attr, start, arg)?; this.write_null(dest)?; @@ -1250,18 +1086,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "pthread_join" => { let [thread, retval] = this.check_shim_sig( shim_sig!(extern "C" fn(libc::pthread_t, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; this.pthread_join(thread, retval, dest)?; } "pthread_detach" => { let [thread] = this.check_shim_sig( shim_sig!(extern "C" fn(libc::pthread_t) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let res = this.pthread_detach(thread)?; this.write_scalar(res, dest)?; @@ -1269,9 +1101,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "pthread_self" => { let [] = this.check_shim_sig( shim_sig!(extern "C" fn() -> libc::pthread_t), - link_name, - abi, - args, + (link_name, abi, args), )?; let res = this.pthread_self()?; this.write_scalar(res, dest)?; @@ -1279,16 +1109,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "sched_yield" => { // FIXME: This does not have a direct test (#3179). let [] = - this.check_shim_sig(shim_sig!(extern "C" fn() -> i32), link_name, abi, args)?; + this.check_shim_sig(shim_sig!(extern "C" fn() -> i32), (link_name, abi, args))?; this.sched_yield()?; this.write_null(dest)?; } "nanosleep" => { let [duration, rem] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.nanosleep(duration, rem)?; this.write_scalar(result, dest)?; @@ -1302,9 +1130,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let [clock_id, flags, req, rem] = this.check_shim_sig( shim_sig!(extern "C" fn(libc::clockid_t, i32, *_, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.clock_nanosleep(clock_id, flags, req, rem)?; this.write_scalar(result, dest)?; @@ -1315,9 +1141,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let [pid, cpusetsize, mask] = this.check_shim_sig( shim_sig!(extern "C" fn(libc::pid_t, usize, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let pid = this.read_scalar(pid)?.to_u32()?; let cpusetsize = this.read_target_usize(cpusetsize)?; @@ -1372,9 +1196,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let [pid, cpusetsize, mask] = this.check_shim_sig( shim_sig!(extern "C" fn(libc::pid_t, usize, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let pid = this.read_scalar(pid)?.to_u32()?; let cpusetsize = this.read_target_usize(cpusetsize)?; @@ -1431,12 +1253,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Miscellaneous "isatty" => { - let [fd] = this.check_shim_sig( - shim_sig!(extern "C" fn(i32) -> i32), - link_name, - abi, - args, - )?; + let [fd] = this + .check_shim_sig(shim_sig!(extern "C" fn(i32) -> i32), (link_name, abi, args))?; let result = this.isatty(fd)?; this.write_scalar(result, dest)?; } @@ -1444,9 +1262,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [prepare, parent, child] = this.check_shim_sig( shim_sig!(extern "C" fn(fn(..) -> _, fn(..) -> _, fn(..) -> _) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; this.read_pointer(prepare)?; this.read_pointer(parent)?; @@ -1457,9 +1273,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "strerror_r" => { let [errnum, buf, buflen] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, usize) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.strerror_r(errnum, buf, buflen)?; this.write_scalar(result, dest)?; @@ -1474,9 +1288,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let [buf, bufsize] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, usize) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let buf = this.read_pointer(buf)?; let bufsize = this.read_target_usize(bufsize)?; @@ -1503,9 +1315,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let [ptr, len, flags] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, usize, u32) -> isize), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr = this.read_pointer(ptr)?; let len = this.read_target_usize(len)?; @@ -1521,9 +1331,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let [ptr, len] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, usize) -> ()), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr = this.read_pointer(ptr)?; let len = this.read_target_usize(len)?; @@ -1551,9 +1359,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // This function looks and behaves exactly like miri_start_unwind. let [payload] = this.check_shim_sig( shim_sig!(extern "C" fn(*_) -> unwind::_Unwind_Reason_Code), - link_name, - abi, - args, + (link_name, abi, args), )?; this.handle_miri_start_unwind(payload)?; return interp_ok(EmulateItemResult::NeedsUnwind); @@ -1561,9 +1367,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "getuid" | "geteuid" => { let [] = this.check_shim_sig( shim_sig!(extern "C" fn() -> libc::uid_t), - link_name, - abi, - args, + (link_name, abi, args), )?; // For now, just pretend we always have this fixed UID. this.write_int(UID, dest)?; diff --git a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs index 5a8df974a5bbb..e132409589a72 100644 --- a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs @@ -178,9 +178,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://github.com/freebsd/freebsd-src/blob/3542d60fb8042474f66fbf2d779ed8c5a80d0f78/lib/libc/gen/uname.c#L44 let [size, uname] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.uname(uname, Some(size))?; this.write_scalar(result, dest)?; diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs index 2c1f891ceaff9..79134ec9a5058 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -42,9 +42,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // has O_CREAT (or on linux O_TMPFILE, but miri doesn't support that) set let ([path_raw, flag], varargs) = this.check_shim_sig_variadic( shim_sig_variadic!(extern "C" fn(*_, i32) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.open(path_raw, flag, varargs)?; this.write_scalar(result, dest)?; @@ -53,9 +51,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [fd, buf, count, offset] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, usize, libc::off64_t) -> isize), - link_name, - abi, - args, + (link_name, abi, args), )?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; @@ -67,9 +63,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [fd, buf, n, offset] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, usize, libc::off64_t) -> isize), - link_name, - abi, - args, + (link_name, abi, args), )?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; @@ -82,9 +76,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [fd, offset, whence] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, libc::off64_t, i32) -> libc::off64_t), - link_name, - abi, - args, + (link_name, abi, args), )?; let fd = this.read_scalar(fd)?.to_i32()?; let offset = this.read_scalar(offset)?.to_int(offset.layout.size)?; @@ -94,9 +86,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "ftruncate64" => { let [fd, length] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, libc::off64_t) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let fd = this.read_scalar(fd)?.to_i32()?; let length = this.read_scalar(length)?.to_int(length.layout.size)?; @@ -106,9 +96,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "posix_fallocate64" => { let [fd, offset, len] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, libc::off64_t, libc::off64_t) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let fd = this.read_scalar(fd)?.to_i32()?; @@ -122,9 +110,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "fallocate" => { let [fd, mode, offset, len] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, i32, libc::off_t, libc::off_t) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let fd = this.read_scalar(fd)?.to_i32()?; @@ -141,9 +127,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "fallocate64" => { let [fd, mode, offset, len] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, i32, libc::off64_t, libc::off64_t) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let fd = this.read_scalar(fd)?.to_i32()?; @@ -259,9 +243,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "mremap" => { let ([old_address, old_size, new_size, flags], _) = this.check_shim_sig_variadic( shim_sig_variadic!(extern "C" fn(*_, usize, usize, i32) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr = this.mremap(old_address, old_size, new_size, flags)?; this.write_scalar(ptr, dest)?; diff --git a/src/tools/miri/src/shims/unix/linux_like/syscall.rs b/src/tools/miri/src/shims/unix/linux_like/syscall.rs index 7dc036d8890b6..34a84dc60da73 100644 --- a/src/tools/miri/src/shims/unix/linux_like/syscall.rs +++ b/src/tools/miri/src/shims/unix/linux_like/syscall.rs @@ -17,9 +17,7 @@ pub fn syscall<'tcx>( ) -> InterpResult<'tcx> { let ([op], varargs) = ecx.check_shim_sig_variadic( shim_sig_variadic!(extern "C" fn(isize) -> isize), - link_name, - abi, - args, + (link_name, abi, args), )?; // The syscall variadic function is legal to call with more arguments than needed, // extra arguments are simply ignored. The important check is that when we use an diff --git a/src/tools/miri/src/shims/unix/linux_like/thread.rs b/src/tools/miri/src/shims/unix/linux_like/thread.rs index 5555bc92b972a..5e275daf81d15 100644 --- a/src/tools/miri/src/shims/unix/linux_like/thread.rs +++ b/src/tools/miri/src/shims/unix/linux_like/thread.rs @@ -17,9 +17,7 @@ pub fn prctl<'tcx>( ) -> InterpResult<'tcx> { let ([op], varargs) = ecx.check_shim_sig_variadic( shim_sig_variadic!(extern "C" fn(i32) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let pr_set_name = ecx.eval_libc_i32("PR_SET_NAME"); diff --git a/src/tools/miri/src/shims/unix/netbsd/foreign_items.rs b/src/tools/miri/src/shims/unix/netbsd/foreign_items.rs index c265cef273a57..d2cc18950fefd 100644 --- a/src/tools/miri/src/shims/unix/netbsd/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/netbsd/foreign_items.rs @@ -22,8 +22,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // Environment "__unsetenv13" => { - let [name] = - this.check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), link_name, abi, args)?; + let [name] = this + .check_shim_sig(shim_sig!(extern "C" fn(*_) -> i32), (link_name, abi, args))?; let result = this.unsetenv(name)?; this.write_scalar(result, dest)?; } @@ -31,7 +31,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Miscellaneous "__errno" => { let [] = - this.check_shim_sig(shim_sig!(extern "C" fn() -> *_), link_name, abi, args)?; + this.check_shim_sig(shim_sig!(extern "C" fn() -> *_), (link_name, abi, args))?; let errno_place = this.last_error_place()?; this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?; } diff --git a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs index 2b885aedecc11..4a1ced0f9514a 100644 --- a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs @@ -118,9 +118,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "__xnet_socket" | "__xnet7_socket" => { let [domain, type_, protocol] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, i32, i32) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.socket(domain, type_, protocol)?; this.write_scalar(result, dest)?; @@ -128,9 +126,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "__xnet_bind" => { let [socket, address, address_len] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, libc::socklen_t) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.bind(socket, address, address_len)?; this.write_scalar(result, dest)?; @@ -138,18 +134,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "__xnet_connect" => { let [socket, address, address_len] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *_, libc::socklen_t) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; this.connect(socket, address, address_len, dest)?; } "__xnet_getaddrinfo" => { let [node, service, hints, res] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, *_, *_, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.getaddrinfo(node, service, hints, res)?; this.write_scalar(result, dest)?; @@ -157,9 +149,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "__xnet_getsockopt" => { let [socket, level, option_name, option_value, option_len] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, i32, i32, *_, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.getsockopt(socket, level, option_name, option_value, option_len)?; diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index d435bac532ed3..c0fa7118ef765 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -151,9 +151,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [name, buf, size] = this.check_shim_sig( shim_sig!(extern "system" fn(*_, *_, u32) -> u32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.GetEnvironmentVariableW(name, buf, size)?; this.write_scalar(result, dest)?; @@ -162,9 +160,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [name, value] = this.check_shim_sig( shim_sig!(extern "system" fn(*_, *_) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.SetEnvironmentVariableW(name, value)?; this.write_scalar(result, dest)?; @@ -173,9 +169,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [] = this.check_shim_sig( shim_sig!(extern "system" fn() -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.GetEnvironmentStringsW()?; this.write_pointer(result, dest)?; @@ -184,9 +178,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [env_block] = this.check_shim_sig( shim_sig!(extern "system" fn(*_) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.FreeEnvironmentStringsW(env_block)?; this.write_scalar(result, dest)?; @@ -195,9 +187,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [size, buf] = this.check_shim_sig( shim_sig!(extern "system" fn(u32, *_) -> u32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.GetCurrentDirectoryW(size, buf)?; this.write_scalar(result, dest)?; @@ -206,9 +196,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [path] = this.check_shim_sig( shim_sig!(extern "system" fn(*_) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.SetCurrentDirectoryW(path)?; this.write_scalar(result, dest)?; @@ -217,9 +205,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [token, buf, size] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::HANDLE, *_, *_) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.GetUserProfileDirectoryW(token, buf, size)?; this.write_scalar(result, dest)?; @@ -228,9 +214,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [] = this.check_shim_sig( shim_sig!(extern "system" fn() -> u32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.GetCurrentProcessId()?; this.write_scalar(result, dest)?; @@ -239,9 +223,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [bufferlength, buffer] = this.check_shim_sig( shim_sig!(extern "system" fn(u32, *_) -> u32), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.GetTempPathW(bufferlength, buffer)?; this.write_scalar(result, dest)?; @@ -273,9 +255,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { *_, ) -> i32 ), - link_name, - abi, - args, + (link_name, abi, args), )?; this.NtWriteFile( handle, @@ -315,9 +295,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { *_, ) -> i32 ), - link_name, - abi, - args, + (link_name, abi, args), )?; this.NtReadFile( handle, @@ -336,9 +314,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [filename, size, buffer, filepart] = this.check_shim_sig( shim_sig!(extern "system" fn(*_, u32, *_, *_) -> u32), - link_name, - abi, - args, + (link_name, abi, args), )?; this.check_no_isolation("`GetFullPathNameW`")?; @@ -388,9 +364,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { winapi::HANDLE, ) -> winapi::HANDLE ), - link_name, - abi, - args, + (link_name, abi, args), )?; let handle = this.CreateFileW( file_name, @@ -406,9 +380,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetFileInformationByHandle" => { let [handle, info] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::HANDLE, *_) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; let res = this.GetFileInformationByHandle(handle, info)?; this.write_scalar(res, dest)?; @@ -423,9 +395,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { u32, ) -> winapi::BOOL ), - link_name, - abi, - args, + (link_name, abi, args), )?; let res = this.SetFileInformationByHandle(handle, class, info, size)?; this.write_scalar(res, dest)?; @@ -433,9 +403,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "FlushFileBuffers" => { let [handle] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::HANDLE) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; let res = this.FlushFileBuffers(handle)?; this.write_scalar(res, dest)?; @@ -443,9 +411,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "DeleteFileW" => { let [file_name] = this.check_shim_sig( shim_sig!(extern "system" fn(*_) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; let res = this.DeleteFileW(file_name)?; this.write_scalar(res, dest)?; @@ -454,9 +420,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let [file, distance_to_move, new_file_pointer, move_method] = this.check_shim_sig( // i64 is actually a LARGE_INTEGER union of {u32, i32} and {i64} shim_sig!(extern "system" fn(winapi::HANDLE, i64, *_, u32) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; let res = this.SetFilePointerEx(file, distance_to_move, new_file_pointer, move_method)?; @@ -465,9 +429,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "MoveFileExW" => { let [existing_name, new_name, flags] = this.check_shim_sig( shim_sig!(extern "system" fn(*_, *_, u32) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; let res = this.MoveFileExW(existing_name, new_name, flags)?; this.write_scalar(res, dest)?; @@ -478,9 +440,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [handle, flags, size] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::HANDLE, u32, usize) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; this.read_target_isize(handle)?; let flags = this.read_scalar(flags)?.to_u32()?; @@ -506,9 +466,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [handle, flags, ptr] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::HANDLE, u32, *_) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; this.read_target_isize(handle)?; this.read_scalar(flags)?.to_u32()?; @@ -524,9 +482,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [handle, flags, old_ptr, size] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::HANDLE, u32, *_, usize) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; this.read_target_isize(handle)?; this.read_scalar(flags)?.to_u32()?; @@ -550,9 +506,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [ptr] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::HLOCAL) -> winapi::HLOCAL), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr = this.read_pointer(ptr)?; // "If the hMem parameter is NULL, LocalFree ignores the parameter and returns NULL." @@ -567,9 +521,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "SetLastError" => { let [error] = this.check_shim_sig( shim_sig!(extern "system" fn(u32) -> ()), - link_name, - abi, - args, + (link_name, abi, args), )?; let error = this.read_scalar(error)?; this.set_last_error(error)?; @@ -577,9 +529,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetLastError" => { let [] = this.check_shim_sig( shim_sig!(extern "system" fn() -> u32), - link_name, - abi, - args, + (link_name, abi, args), )?; let last_error = this.get_last_error()?; this.write_scalar(last_error, dest)?; @@ -587,9 +537,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "RtlNtStatusToDosError" => { let [status] = this.check_shim_sig( shim_sig!(extern "system" fn(i32) -> u32), - link_name, - abi, - args, + (link_name, abi, args), )?; let status = this.read_scalar(status)?.to_u32()?; let err = match status { @@ -615,9 +563,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Also called from `page_size` crate. let [system_info] = this.check_shim_sig( shim_sig!(extern "system" fn(*_) -> ()), - link_name, - abi, - args, + (link_name, abi, args), )?; let system_info = this.deref_pointer_as(system_info, this.windows_ty_layout("SYSTEM_INFO"))?; @@ -644,9 +590,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Create key and return it. let [] = this.check_shim_sig( shim_sig!(extern "system" fn() -> u32), - link_name, - abi, - args, + (link_name, abi, args), )?; let key = this.machine.tls.create_tls_key(None, dest.layout.size)?; this.write_scalar(Scalar::from_uint(key, dest.layout.size), dest)?; @@ -655,9 +599,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [key] = this.check_shim_sig( shim_sig!(extern "system" fn(u32) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; let key = u128::from(this.read_scalar(key)?.to_u32()?); let active_thread = this.active_thread(); @@ -668,9 +610,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [key, new_ptr] = this.check_shim_sig( shim_sig!(extern "system" fn(u32, *_) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; let key = u128::from(this.read_scalar(key)?.to_u32()?); let active_thread = this.active_thread(); @@ -684,9 +624,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [key] = this.check_shim_sig( shim_sig!(extern "system" fn(u32) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; let key = u128::from(this.read_scalar(key)?.to_u32()?); this.machine.tls.delete_tls_key(key)?; @@ -701,9 +639,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Create key and return it. let [dtor] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::PFLS_CALLBACK_FUNCTION) -> u32), - link_name, - abi, - args, + (link_name, abi, args), )?; let dtor = this.read_pointer(dtor)?; @@ -724,9 +660,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [key] = this.check_shim_sig( shim_sig!(extern "system" fn(u32) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; let key = u128::from(this.read_scalar(key)?.to_u32()?); let active_thread = this.active_thread(); @@ -737,9 +671,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [key, new_ptr] = this.check_shim_sig( shim_sig!(extern "system" fn(u32, *_) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; let key = u128::from(this.read_scalar(key)?.to_u32()?); let active_thread = this.active_thread(); @@ -753,9 +685,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [key] = this.check_shim_sig( shim_sig!(extern "system" fn(u32) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; let key = u128::from(this.read_scalar(key)?.to_u32()?); let tls_entry = this.machine.tls.delete_tls_key(key)?; @@ -774,9 +704,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [] = this.check_shim_sig( shim_sig!(extern "system" fn() -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; // Return FALSE, as Miri does not support fibers. @@ -788,9 +716,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [] = this.check_shim_sig( shim_sig!(extern "system" fn() -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; this.write_pointer( this.machine.cmd_line.expect("machine must be initialized"), @@ -803,9 +729,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [filetime] = this.check_shim_sig( shim_sig!(extern "system" fn(*_) -> ()), - link_name, - abi, - args, + (link_name, abi, args), )?; this.GetSystemTimeAsFileTime(link_name.as_str(), filetime)?; } @@ -813,9 +737,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [performance_count] = this.check_shim_sig( shim_sig!(extern "system" fn(*_) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.QueryPerformanceCounter(performance_count)?; this.write_scalar(result, dest)?; @@ -824,9 +746,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [frequency] = this.check_shim_sig( shim_sig!(extern "system" fn(*_) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.QueryPerformanceFrequency(frequency)?; this.write_scalar(result, dest)?; @@ -835,9 +755,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [timeout] = this.check_shim_sig( shim_sig!(extern "system" fn(u32) -> ()), - link_name, - abi, - args, + (link_name, abi, args), )?; this.Sleep(timeout)?; @@ -846,9 +764,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [attributes, name, flags, access] = this.check_shim_sig( shim_sig!(extern "system" fn(*_, *_, u32, u32) -> winapi::HANDLE), - link_name, - abi, - args, + (link_name, abi, args), )?; this.read_pointer(attributes)?; this.read_pointer(name)?; @@ -864,18 +780,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "InitOnceBeginInitialize" => { let [ptr, flags, pending, context] = this.check_shim_sig( shim_sig!(extern "system" fn(*_, u32, *_, *_) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; this.InitOnceBeginInitialize(ptr, flags, pending, context, dest)?; } "InitOnceComplete" => { let [ptr, flags, context] = this.check_shim_sig( shim_sig!(extern "system" fn(*_, u32, *_) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; let result = this.InitOnceComplete(ptr, flags, context)?; this.write_scalar(result, dest)?; @@ -885,9 +797,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let [ptr_op, compare_op, size_op, timeout_op] = this.check_shim_sig( // First pointer is volatile shim_sig!(extern "system" fn(*_, *_, usize, u32) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; this.WaitOnAddress(ptr_op, compare_op, size_op, timeout_op, dest)?; @@ -896,9 +806,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [ptr_op] = this.check_shim_sig( shim_sig!(extern "system" fn(*_) -> ()), - link_name, - abi, - args, + (link_name, abi, args), )?; this.WakeByAddressSingle(ptr_op)?; @@ -907,9 +815,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [ptr_op] = this.check_shim_sig( shim_sig!(extern "system" fn(*_) -> ()), - link_name, - abi, - args, + (link_name, abi, args), )?; this.WakeByAddressAll(ptr_op)?; @@ -920,9 +826,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [module, proc_name] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::HMODULE, *_) -> winapi::FARPROC), - link_name, - abi, - args, + (link_name, abi, args), )?; this.read_target_isize(module)?; let name = this.read_c_str(this.read_pointer(proc_name)?)?; @@ -949,9 +853,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { *_, ) -> winapi::HANDLE ), - link_name, - abi, - args, + (link_name, abi, args), )?; let thread_id = @@ -962,9 +864,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "WaitForSingleObject" => { let [handle, timeout] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::HANDLE, u32) -> u32), - link_name, - abi, - args, + (link_name, abi, args), )?; this.WaitForSingleObject(handle, timeout, dest)?; @@ -972,9 +872,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetCurrentProcess" => { let [] = this.check_shim_sig( shim_sig!(extern "system" fn() -> winapi::HANDLE), - link_name, - abi, - args, + (link_name, abi, args), )?; this.write_scalar( @@ -985,9 +883,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetCurrentThread" => { let [] = this.check_shim_sig( shim_sig!(extern "system" fn() -> winapi::HANDLE), - link_name, - abi, - args, + (link_name, abi, args), )?; this.write_scalar( @@ -998,9 +894,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "SetThreadDescription" => { let [handle, name] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::HANDLE, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let handle = this.read_handle(handle, "SetThreadDescription")?; @@ -1018,9 +912,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetThreadDescription" => { let [handle, name_ptr] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::HANDLE, *_) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let handle = this.read_handle(handle, "GetThreadDescription")?; @@ -1046,9 +938,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetThreadId" => { let [handle] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::HANDLE) -> u32), - link_name, - abi, - args, + (link_name, abi, args), )?; let handle = this.read_handle(handle, "GetThreadId")?; let thread = match handle { @@ -1061,9 +951,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetCurrentThreadId" => { let [] = this.check_shim_sig( shim_sig!(extern "system" fn() -> u32), - link_name, - abi, - args, + (link_name, abi, args), )?; this.write_scalar(Scalar::from_u32(this.active_thread().to_u32()), dest)?; } @@ -1073,9 +961,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [code] = this.check_shim_sig( shim_sig!(extern "system" fn(u32) -> ()), - link_name, - abi, - args, + (link_name, abi, args), )?; // Windows technically uses u32, but we unify everything to a Unix-style i32. let code = this.read_scalar(code)?.to_i32()?; @@ -1087,9 +973,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let [ptr, len] = this.check_shim_sig( // Returns winapi::BOOLEAN, which is a byte shim_sig!(extern "system" fn(*_, u32) -> u8), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr = this.read_pointer(ptr)?; let len = this.read_scalar(len)?.to_u32()?; @@ -1101,9 +985,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // used by `std` let [ptr, len] = this.check_shim_sig( shim_sig!(extern "system" fn(*_, usize) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; let ptr = this.read_pointer(ptr)?; let len = this.read_target_usize(len)?; @@ -1114,9 +996,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // used by getrandom 0.2 let [algorithm, ptr, len, flags] = this.check_shim_sig( shim_sig!(extern "system" fn(*_, *_, u32, u32) -> i32), - link_name, - abi, - args, + (link_name, abi, args), )?; let algorithm = this.read_scalar(algorithm)?; let algorithm = algorithm.to_target_usize(this)?; @@ -1154,9 +1034,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `term` needs this, so we fake it. let [console, buffer_info] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::HANDLE, *_) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; this.read_target_isize(console)?; // FIXME: this should use deref_pointer_as, but CONSOLE_SCREEN_BUFFER_INFO is not in std @@ -1169,9 +1047,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [which] = this.check_shim_sig( shim_sig!(extern "system" fn(u32) -> winapi::HANDLE), - link_name, - abi, - args, + (link_name, abi, args), )?; let res = this.GetStdHandle(which)?; this.write_scalar(res, dest)?; @@ -1190,9 +1066,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { u32, ) -> winapi::BOOL ), - link_name, - abi, - args, + (link_name, abi, args), )?; let res = this.DuplicateHandle( src_proc, @@ -1208,9 +1082,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "CloseHandle" => { let [handle] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::HANDLE) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; let ret = this.CloseHandle(handle)?; @@ -1221,9 +1093,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // FIXME: This does not have a direct test (#3179). let [handle, filename, size] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::HMODULE, *_, u32) -> u32), - link_name, - abi, - args, + (link_name, abi, args), )?; this.check_no_isolation("`GetModuleFileNameW`")?; @@ -1263,9 +1133,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { shim_sig!( extern "system" fn(u32, *_, u32, u32, *_, u32, *_) -> u32 ), - link_name, - abi, - args, + (link_name, abi, args), )?; let flags = this.read_scalar(flags)?.to_u32()?; @@ -1312,9 +1180,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // This function looks and behaves exactly like miri_start_unwind. let [payload] = this.check_shim_sig( shim_sig!(extern "C" fn(*_) -> unwind::_Unwind_Reason_Code), - link_name, - abi, - args, + (link_name, abi, args), )?; this.handle_miri_start_unwind(payload)?; return interp_ok(EmulateItemResult::NeedsUnwind); @@ -1325,9 +1191,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetProcessHeap" if this.frame_in_std() => { let [] = this.check_shim_sig( shim_sig!(extern "system" fn() -> winapi::HANDLE), - link_name, - abi, - args, + (link_name, abi, args), )?; // Just fake a HANDLE // It's fine to not use the Handle type here because its a stub @@ -1336,9 +1200,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetModuleHandleA" if this.frame_in_std() => { let [_module_name] = this.check_shim_sig( shim_sig!(extern "system" fn(*_) -> winapi::HMODULE), - link_name, - abi, - args, + (link_name, abi, args), )?; // We need to return something non-null here to make `compat_fn!` work. this.write_int(1, dest)?; @@ -1346,9 +1208,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "SetConsoleTextAttribute" if this.frame_in_std() => { let [_console_output, _attribute] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::HANDLE, u16) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; // Pretend these does not exist / nothing happened, by returning zero. this.write_null(dest)?; @@ -1356,9 +1216,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetConsoleMode" if this.frame_in_std() => { let [console, mode] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::HANDLE, *_) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; this.read_target_isize(console)?; this.deref_pointer_as(mode, this.machine.layouts.u32)?; @@ -1368,9 +1226,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetFileType" if this.frame_in_std() => { let [_file] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::HANDLE) -> u32), - link_name, - abi, - args, + (link_name, abi, args), )?; // Return unknown file type. this.write_null(dest)?; @@ -1378,9 +1234,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "AddVectoredExceptionHandler" if this.frame_in_std() => { let [_first, _handler] = this.check_shim_sig( shim_sig!(extern "system" fn(u32, *_) -> *_), - link_name, - abi, - args, + (link_name, abi, args), )?; // Any non zero value works for the stdlib. This is just used for stack overflows anyway. this.write_int(1, dest)?; @@ -1388,9 +1242,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "SetThreadStackGuarantee" if this.frame_in_std() => { let [_stack_size_in_bytes] = this.check_shim_sig( shim_sig!(extern "system" fn(*_) -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; // Any non zero value works for the stdlib. This is just used for stack overflows anyway. this.write_int(1, dest)?; @@ -1399,9 +1251,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "SwitchToThread" if this.frame_in_std() => { let [] = this.check_shim_sig( shim_sig!(extern "system" fn() -> winapi::BOOL), - link_name, - abi, - args, + (link_name, abi, args), )?; this.yield_active_thread(); From 8aaa1fd0ecde8c49bf49942cd3f7e40859763ff7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 24 Aug 2026 08:03:38 +0200 Subject: [PATCH 10/54] run _Unwind_RaiseException test on windows-gnu --- src/tools/miri/src/shims/windows/foreign_items.rs | 1 - src/tools/miri/tests/pass/panic/unwind_dwarf.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index c0fa7118ef765..7a4a8550e80fc 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -1167,7 +1167,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "_Unwind_RaiseException" => { - // FIXME: This does not have a direct test (#3179). // This is not formally part of POSIX, but it is very wide-spread on POSIX systems. // It was originally specified as part of the Itanium C++ ABI: // https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html#base-throw. diff --git a/src/tools/miri/tests/pass/panic/unwind_dwarf.rs b/src/tools/miri/tests/pass/panic/unwind_dwarf.rs index aaecacd95ec9a..4548a177a85e8 100644 --- a/src/tools/miri/tests/pass/panic/unwind_dwarf.rs +++ b/src/tools/miri/tests/pass/panic/unwind_dwarf.rs @@ -1,4 +1,4 @@ -//@ignore-target: windows # Windows uses a different unwinding mechanism +//@ignore-target: windows-msvc # MSVC uses a different unwinding mechanism #![feature(core_intrinsics, panic_unwind, rustc_attrs)] #![allow(internal_features)] From 210fd61779ba428eae252ff6d53ac13e87958808 Mon Sep 17 00:00:00 2001 From: khyperia <953151+khyperia@users.noreply.github.com> Date: Mon, 24 Aug 2026 08:54:48 +0200 Subject: [PATCH 11/54] add internal DSL for testing binders --- compiler/rustc_ast/src/ast.rs | 103 ++++++--- compiler/rustc_ast/src/visit.rs | 14 ++ compiler/rustc_ast_lowering/src/index.rs | 10 + compiler/rustc_ast_lowering/src/item.rs | 110 +++++++++- compiler/rustc_ast_passes/src/feature_gate.rs | 10 + .../rustc_ast_pretty/src/pprust/state/item.rs | 3 + compiler/rustc_attr_ir/src/target.rs | 1 + compiler/rustc_builtin_macros/src/lib.rs | 2 + .../src/test_binder_constraints.rs | 42 ++++ compiler/rustc_feature/src/unstable.rs | 2 + compiler/rustc_hir/src/def.rs | 13 +- compiler/rustc_hir/src/hir.rs | 55 ++++- compiler/rustc_hir/src/intravisit.rs | 75 +++++++ compiler/rustc_hir/src/target_impls.rs | 1 + .../rustc_hir_analysis/src/check/check.rs | 25 ++- .../rustc_hir_analysis/src/check/wfcheck.rs | 196 +++++++++++++++++- compiler/rustc_hir_analysis/src/collect.rs | 140 ++++++++++++- .../src/collect/resolve_bound_vars.rs | 71 ++++++- .../rustc_hir_analysis/src/collect/type_of.rs | 3 +- .../src/hir_ty_lowering/mod.rs | 3 +- compiler/rustc_hir_id/src/definitions.rs | 10 +- compiler/rustc_hir_pretty/src/lib.rs | 5 + compiler/rustc_infer/src/infer/context.rs | 22 +- compiler/rustc_infer/src/infer/mod.rs | 50 ++++- .../src/infer/outlives/obligations.rs | 10 +- .../src/infer/snapshot/undo_log.rs | 2 +- .../src/infer/solver_region_constraints.rs | 24 +-- .../rustc_lint/src/types/improper_ctypes.rs | 3 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 32 ++- compiler/rustc_metadata/src/rmeta/table.rs | 1 + compiler/rustc_middle/src/hir/map.rs | 7 +- compiler/rustc_middle/src/hir/mod.rs | 4 +- compiler/rustc_middle/src/ty/mod.rs | 3 +- compiler/rustc_middle/src/ty/sty.rs | 3 +- compiler/rustc_middle/src/ty/util.rs | 3 +- compiler/rustc_parse/src/parser/generics.rs | 14 +- compiler/rustc_parse/src/parser/item.rs | 104 ++++++++++ compiler/rustc_passes/src/dead.rs | 3 +- compiler/rustc_passes/src/input_stats.rs | 6 +- compiler/rustc_passes/src/reachable.rs | 3 +- compiler/rustc_privacy/src/lib.rs | 8 +- compiler/rustc_public/src/unstable/mod.rs | 3 +- .../rustc_resolve/src/build_reduced_graph.rs | 6 +- compiler/rustc_resolve/src/def_collector.rs | 1 + .../src/effective_visibilities.rs | 3 +- compiler/rustc_resolve/src/late.rs | 100 +++++++-- .../src/cfi/typeid/itanium_cxx_abi/encode.rs | 3 +- compiler/rustc_span/src/symbol.rs | 3 + compiler/rustc_symbol_mangling/src/v0.rs | 3 +- compiler/rustc_ty_utils/src/implied_bounds.rs | 3 +- compiler/rustc_ty_utils/src/opaque_types.rs | 3 +- compiler/rustc_ty_walk/src/lib.rs | 3 +- library/core/src/internal_macros.rs | 10 + src/librustdoc/formats/item_type.rs | 3 +- src/librustdoc/html/span_map.rs | 1 + .../passes/collect_intra_doc_links.rs | 5 +- src/librustdoc/visit_ast.rs | 1 + .../clippy/book/src/lint_configuration.md | 2 +- src/tools/clippy/clippy_config/src/types.rs | 10 +- .../src/arbitrary_source_item_ordering.rs | 1 + .../src/definition_in_module_root.rs | 3 +- .../clippy_lints/src/item_name_repetitions.rs | 6 +- .../clippy_lints/src/manual_float_methods.rs | 3 +- .../clippy_lints/src/min_ident_chars.rs | 3 +- .../clippy/clippy_lints/src/missing_doc.rs | 3 +- .../clippy_utils/src/check_proc_macro.rs | 1 + src/tools/clippy/clippy_utils/src/lib.rs | 4 +- .../default_exp/clippy.toml | 2 +- src/tools/rustfmt/src/visitor.rs | 1 + .../test-infra-fails-properly.rs | 70 +++++++ .../test-infra-fails-properly.stderr | 69 ++++++ .../test-infra-works.rs | 44 ++++ .../feature-gate-test-binder-constraints.rs | 8 + ...eature-gate-test-binder-constraints.stderr | 12 ++ 74 files changed, 1431 insertions(+), 158 deletions(-) create mode 100644 compiler/rustc_builtin_macros/src/test_binder_constraints.rs create mode 100644 tests/ui/assumptions_on_binders/test-infra-fails-properly.rs create mode 100644 tests/ui/assumptions_on_binders/test-infra-fails-properly.stderr create mode 100644 tests/ui/assumptions_on_binders/test-infra-works.rs create mode 100644 tests/ui/feature-gates/feature-gate-test-binder-constraints.rs create mode 100644 tests/ui/feature-gates/feature-gate-test-binder-constraints.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 45ea2dcd121ff..2918566ea7169 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3737,29 +3737,7 @@ impl Item { } pub fn opt_generics(&self) -> Option<&Generics> { - match &self.kind { - ItemKind::ExternCrate(..) - | ItemKind::ConstBlock(_) - | ItemKind::Use(_) - | ItemKind::Mod(..) - | ItemKind::ForeignMod(_) - | ItemKind::GlobalAsm(_) - | ItemKind::MacCall(_) - | ItemKind::Delegation(_) - | ItemKind::DelegationMac(_) - | ItemKind::MacroDef(..) => None, - ItemKind::Static(_) => None, - ItemKind::Const(i) => Some(&i.generics), - ItemKind::Fn(i) => Some(&i.generics), - ItemKind::TyAlias(i) => Some(&i.generics), - ItemKind::TraitAlias(i) => Some(&i.generics), - - ItemKind::Enum(_, generics, _) - | ItemKind::Struct(_, generics, _) - | ItemKind::Union(_, generics, _) => Some(&generics), - ItemKind::Trait(i) => Some(&i.generics), - ItemKind::Impl(i) => Some(&i.generics), - } + self.kind.generics() } } @@ -4096,6 +4074,57 @@ impl Guard { } } +#[derive(Clone, Encodable, Decodable, Debug, Walkable)] +pub struct TestBinderConstraints { + pub generics: Generics, + pub body: Box, +} + +#[derive(Clone, Encodable, Decodable, Debug, Walkable)] +pub struct TestBinderBody { + pub foralls: ThinVec, + pub exists: ThinVec, + pub constraints: Vec, +} + +#[derive(Clone, Encodable, Decodable, Debug, Walkable)] +pub struct TestBinderForall { + pub span: Span, + pub node_id: NodeId, + pub generics: Generics, + pub body: TestBinderBody, + pub assert_on_exit: Option>, +} + +#[derive(Clone, Encodable, Decodable, Debug, Walkable)] +pub struct TestBinderExists { + pub span: Span, + pub node_id: NodeId, + pub params: ThinVec, + pub body: TestBinderBody, +} + +#[derive(Clone, Encodable, Decodable, Debug, Walkable)] +pub enum TestBinderConstraint { + And { + items: ThinVec, + }, + Or { + items: ThinVec, + }, + Lifetime { + #[visitable(extra = LifetimeCtxt::Bound)] + lhs: Lifetime, + #[visitable(extra = LifetimeCtxt::Bound)] + rhs: Lifetime, + }, + Type { + lhs: Box, + #[visitable(extra = LifetimeCtxt::Bound)] + rhs: Lifetime, + }, +} + // Adding a new variant? Please update `test_item` in `tests/ui/macros/stringify.rs`. #[derive(Clone, Encodable, Decodable, Debug)] pub enum ItemKind { @@ -4177,6 +4206,8 @@ pub enum ItemKind { /// A list or glob delegation item (`reuse prefix::{a, b, c}`, `reuse prefix::*`). /// Treated similarly to a macro call and expanded early. DelegationMac(Box), + /// A `test_binder_constraints!()`. Perma-unstable, used only for rustc tests. + TestBinderConstraints(Box), } impl ItemKind { @@ -4203,7 +4234,8 @@ impl ItemKind { | ItemKind::GlobalAsm(_) | ItemKind::Impl(_) | ItemKind::MacCall(_) - | ItemKind::DelegationMac(_) => None, + | ItemKind::DelegationMac(_) + | ItemKind::TestBinderConstraints(_) => None, } } @@ -4211,9 +4243,22 @@ impl ItemKind { pub fn article(&self) -> &'static str { use ItemKind::*; match self { - Use(..) | Static(..) | Const(..) | ConstBlock(..) | Fn(..) | Mod(..) - | GlobalAsm(..) | TyAlias(..) | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) - | MacroDef(..) | Delegation(..) | DelegationMac(..) => "a", + Use(..) + | Static(..) + | Const(..) + | ConstBlock(..) + | Fn(..) + | Mod(..) + | GlobalAsm(..) + | TyAlias(..) + | Struct(..) + | Union(..) + | Trait(..) + | TraitAlias(..) + | MacroDef(..) + | Delegation(..) + | DelegationMac(..) + | TestBinderConstraints(..) => "a", ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an", } } @@ -4240,6 +4285,7 @@ impl ItemKind { ItemKind::Impl { .. } => "implementation", ItemKind::Delegation(..) => "delegated function", ItemKind::DelegationMac(..) => "delegation", + ItemKind::TestBinderConstraints(..) => "test_binder_constraints!", } } @@ -4253,7 +4299,8 @@ impl ItemKind { | Self::Union(_, generics, _) | Self::Trait(Trait { generics, .. }) | Self::TraitAlias(TraitAlias { generics, .. }) - | Self::Impl(Impl { generics, .. }) => Some(generics), + | Self::Impl(Impl { generics, .. }) + | Self::TestBinderConstraints(TestBinderConstraints { generics, .. }) => Some(generics), Self::ExternCrate(..) | Self::Use(..) diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 6b7ea072da61b..68cf07c61682f 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -399,6 +399,9 @@ macro_rules! common_visitor_and_walkers { ThinVec, ThinVec, ThinVec, + ThinVec, + ThinVec, + ThinVec, ThinVec>, ThinVec, ThinVec, @@ -605,6 +608,11 @@ macro_rules! common_visitor_and_walkers { fn visit_poly_trait_ref(PolyTraitRef); fn visit_precise_capturing_arg(PreciseCapturingArg); fn visit_qself(QSelf); + fn visit_test_binder_body(TestBinderBody); + fn visit_test_binder_constraint(TestBinderConstraint); + fn visit_test_binder_constraints(TestBinderConstraints); + fn visit_test_binder_exists(TestBinderExists); + fn visit_test_binder_forall(TestBinderForall); fn visit_trait_ref(TraitRef); fn visit_ty_pat(TyPat); fn visit_ty(Ty); @@ -870,6 +878,8 @@ macro_rules! common_visitor_and_walkers { visit_visitable!($($mut)? vis, delegation), ItemKind::DelegationMac(dm) => visit_visitable!($($mut)? vis, dm), + ItemKind::TestBinderConstraints(item) => + visit_visitable!($($mut)? vis, item), } V::Result::output() } @@ -1133,6 +1143,10 @@ macro_rules! common_visitor_and_walkers { pub fn walk_poly_trait_ref(PolyTraitRef); pub fn walk_precise_capturing_arg(PreciseCapturingArg); pub fn walk_qself(QSelf); + pub fn walk_test_binder_body(TestBinderBody); + pub fn walk_test_binder_constraint(TestBinderConstraint); + pub fn walk_test_binder_exists(TestBinderExists); + pub fn walk_test_binder_forall(TestBinderForall); pub fn walk_trait_ref(TraitRef); pub fn walk_ty_pat(TyPat); pub fn walk_ty(Ty); diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index be0a1d490da6a..b302a8f45e557 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -431,4 +431,14 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } intravisit::walk_precise_capturing_arg(self, arg); } + + fn visit_test_binder_forall(&mut self, forall: &'hir TestBinderForall<'hir>) -> Self::Result { + self.insert(forall.span, forall.hir_id, Node::TestBinderForall(forall)); + self.with_parent(forall.hir_id, |this| intravisit::walk_test_binder_forall(this, forall)) + } + + fn visit_test_binder_exists(&mut self, exists: &'hir TestBinderExists<'hir>) -> Self::Result { + self.insert(exists.span, exists.hir_id, Node::TestBinderExists(exists)); + self.with_parent(exists.hir_id, |this| intravisit::walk_test_binder_exists(this, exists)) + } } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index fcbe3122c2d3d..d5ef2f9e832dd 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -200,7 +200,8 @@ impl<'hir> LoweringContext<'_, 'hir> { | ItemKind::MacCall(..) | ItemKind::MacroDef(..) | ItemKind::Delegation(..) - | ItemKind::DelegationMac(..) => Vec::new(), + | ItemKind::DelegationMac(..) + | ItemKind::TestBinderConstraints(..) => Vec::new(), } } @@ -574,6 +575,14 @@ impl<'hir> LoweringContext<'_, 'hir> { ItemKind::MacCall(..) | ItemKind::DelegationMac(..) => { panic!("macros should have been expanded by now") } + ItemKind::TestBinderConstraints(TestBinderConstraints { generics, body }) => { + let (generics, body) = self.lower_generics( + generics, + ImplTraitContext::Disallowed(ImplTraitPosition::Bound), + |this| this.lower_test_binder_body(body), + ); + hir::ItemKind::TestBinderConstraints { generics, body: self.arena.alloc(body) } + } } } @@ -2095,4 +2104,103 @@ impl<'hir> LoweringContext<'_, 'hir> { }); hir::WherePredicate { hir_id, span, kind } } + + fn lower_test_binder_body(&mut self, body: &TestBinderBody) -> hir::TestBinderBody<'hir> { + let foralls = self.arena.alloc_from_iter( + body.foralls.iter().map(|forall| self.lower_test_binder_forall(forall)), + ); + let exists = self.arena.alloc_from_iter( + body.exists.iter().map(|exists| self.lower_test_binder_exists(exists)), + ); + let constraints = self.lower_test_binder_constraints_as_and(&body.constraints); + hir::TestBinderBody { foralls, exists, constraints } + } + + fn lower_test_binder_forall( + &mut self, + forall: &TestBinderForall, + ) -> hir::TestBinderForall<'hir> { + let (generics, body) = self.lower_generics( + &forall.generics, + ImplTraitContext::Disallowed(ImplTraitPosition::Bound), + |this| this.lower_test_binder_body(&forall.body), + ); + let assert_on_exit = forall.assert_on_exit.as_ref().map(|assert_on_exit| { + self.arena.alloc(self.lower_test_binder_constraints_as_and(assert_on_exit)) as &_ + }); + hir::TestBinderForall { + span: self.lower_span(forall.span), + hir_id: self.lower_node_id(forall.node_id), + generics, + body: self.arena.alloc(body), + assert_on_exit, + } + } + + fn lower_test_binder_exists( + &mut self, + exists: &TestBinderExists, + ) -> hir::TestBinderExists<'hir> { + let (generics, body) = self.lower_generics( + &Generics { + params: exists.params.clone(), + where_clause: Default::default(), + span: exists.span, + }, + ImplTraitContext::Disallowed(ImplTraitPosition::Bound), + |this| this.lower_test_binder_body(&exists.body), + ); + let params = generics.params; + hir::TestBinderExists { + span: self.lower_span(exists.span), + hir_id: self.lower_node_id(exists.node_id), + params, + body: self.arena.alloc(body), + } + } + + // if there are multiple constraints in a block body, automatically wrap them in an `and {}` + fn lower_test_binder_constraints_as_and( + &mut self, + constraints: &[TestBinderConstraint], + ) -> hir::TestBinderConstraint<'hir> { + if constraints.len() == 1 { + self.lower_test_binder_constraint(&constraints[0]) + } else { + hir::TestBinderConstraint::And { + items: self.arena.alloc_from_iter( + constraints.iter().map(|item| self.lower_test_binder_constraint(item)), + ), + } + } + } + + fn lower_test_binder_constraint( + &mut self, + constraint: &TestBinderConstraint, + ) -> hir::TestBinderConstraint<'hir> { + match constraint { + TestBinderConstraint::And { items } => hir::TestBinderConstraint::And { + items: self.arena.alloc_from_iter( + items.iter().map(|item| self.lower_test_binder_constraint(item)), + ), + }, + TestBinderConstraint::Or { items } => hir::TestBinderConstraint::Or { + items: self.arena.alloc_from_iter( + items.iter().map(|item| self.lower_test_binder_constraint(item)), + ), + }, + TestBinderConstraint::Lifetime { lhs, rhs } => { + let lhs = self.lower_lifetime(lhs, LifetimeSource::Other, lhs.ident.into()); + let rhs = self.lower_lifetime(rhs, LifetimeSource::OutlivesBound, rhs.ident.into()); + hir::TestBinderConstraint::Lifetime { lhs, rhs } + } + TestBinderConstraint::Type { lhs, rhs } => { + let lhs = self + .lower_ty_alloc(lhs, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)); + let rhs = self.lower_lifetime(rhs, LifetimeSource::OutlivesBound, rhs.ident.into()); + hir::TestBinderConstraint::Type { lhs, rhs } + } + } + } } diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 01d81bab55075..d11dab5a99bfd 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -428,6 +428,16 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } visit::walk_assoc_item(self, i, ctxt) } + + fn visit_test_binder_forall(&mut self, forall: &'a ast::TestBinderForall) { + self.check_late_bound_lifetime_defs(&forall.generics.params); + visit::walk_test_binder_forall(self, forall) + } + + fn visit_test_binder_exists(&mut self, exists: &'a ast::TestBinderExists) { + self.check_late_bound_lifetime_defs(&exists.params); + visit::walk_test_binder_exists(self, exists) + } } // ----------------------------------------------------------------------------- diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index 04f78ea7f467a..6dd98bd201f48 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -450,6 +450,9 @@ impl<'a> State<'a> { }, &deleg.body, ), + ast::ItemKind::TestBinderConstraints(_) => { + self.word("test_binder_constraints!(/* pretty-printing not supported */)") + } } self.ann.post(self, AnnNode::Item(item)) } diff --git a/compiler/rustc_attr_ir/src/target.rs b/compiler/rustc_attr_ir/src/target.rs index 8b8cd9db634da..aa36df24f7f78 100644 --- a/compiler/rustc_attr_ir/src/target.rs +++ b/compiler/rustc_attr_ir/src/target.rs @@ -143,6 +143,7 @@ impl Target { ast::ItemKind::MacroDef(..) => Target::MacroDef, ast::ItemKind::Delegation(..) => Target::Delegation { mac: false }, ast::ItemKind::DelegationMac(..) => Target::Delegation { mac: true }, + ast::ItemKind::TestBinderConstraints(..) => Target::MacroCall, } } diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 8f8d8b3149440..db92413e1b162 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -47,6 +47,7 @@ mod offload; mod pattern_type; mod source_util; mod test; +mod test_binder_constraints; mod trace_macros; mod view_type; @@ -100,6 +101,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { pattern_type: pattern_type::expand, std_panic: edition_panic::expand_panic, stringify: source_util::expand_stringify, + test_binder_constraints: test_binder_constraints::expand, trace_macros: trace_macros::expand_trace_macros, unreachable: edition_panic::expand_unreachable, view_type: view_type::expand, diff --git a/compiler/rustc_builtin_macros/src/test_binder_constraints.rs b/compiler/rustc_builtin_macros/src/test_binder_constraints.rs new file mode 100644 index 0000000000000..0c7482672df46 --- /dev/null +++ b/compiler/rustc_builtin_macros/src/test_binder_constraints.rs @@ -0,0 +1,42 @@ +use rustc_ast::tokenstream::TokenStream; +use rustc_ast::{AttrVec, VisibilityKind, ast, token}; +use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult}; +use rustc_span::Span; +use smallvec::SmallVec; + +use crate::diagnostics; + +pub(crate) fn expand<'cx>( + cx: &'cx mut ExtCtxt<'_>, + span: Span, + tts: TokenStream, +) -> MacroExpanderResult<'cx> { + let name = "test_binder_constraints!"; + let mut p = cx.new_parser_from_tts(tts); + if p.token == token::Eof { + cx.dcx().emit_err(diagnostics::OnlyOneArgument { span, name }); + }; + let item = match p.parse_test_binder_constraints() { + Ok(expr) => expr, + Err(diag) => { + let guar = diag.emit(); + return ExpandResult::Ready(DummyResult::any(span, guar)); + } + }; + if p.token != token::Eof { + cx.dcx().emit_err(diagnostics::OnlyOneArgument { span: p.token.span, name }); + } + let item = Box::new(ast::Item { + attrs: AttrVec::default(), + id: ast::DUMMY_NODE_ID, + span, + vis: ast::Visibility { kind: VisibilityKind::Inherited, span: span.shrink_to_lo() }, + kind: ast::ItemKind::TestBinderConstraints(item), + tokens: None, + }); + rustc_expand::base::ExpandResult::Ready(Box::new(MacEager { + expr: None, + items: Some(SmallVec::from_buf([item])), + ty: None, + })) +} diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 00ca1e07c93fd..935a6eee53738 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -288,6 +288,8 @@ declare_features! ( (internal, rustc_attrs, "1.0.0", None), /// Allows using the `#[stable]` and `#[unstable]` attributes. (internal, staged_api, "1.0.0", None), + /// Perma-unstable, only used in the test suite for binders (`for<'a>`). + (internal, test_binder_constraints, "CURRENT_RUSTC_VERSION", None), /// Perma-unstable, only used to test the `incomplete_features` lint. (incomplete, test_incomplete_feature, "1.96.0", None), /// Added for testing unstable lints; perma-unstable. diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 59e4f084ab81b..010ecb1cd3d98 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -201,6 +201,8 @@ pub enum DefKind { /// The definition of a synthetic coroutine body created by the lowering of a /// coroutine-closure, such as an async closure. SyntheticCoroutineBody, + /// Perma-unstable. Used for test infrastructure for binders. + TestBinderConstraints, } impl DefKind { @@ -245,6 +247,7 @@ impl DefKind { DefKind::ExternCrate => "extern crate", DefKind::GlobalAsm => "global assembly block", DefKind::SyntheticCoroutineBody => "synthetic mir body", + DefKind::TestBinderConstraints => "test_binder_constraints!", } } @@ -303,7 +306,8 @@ impl DefKind { | DefKind::GlobalAsm | DefKind::Impl { .. } | DefKind::OpaqueTy - | DefKind::SyntheticCoroutineBody => None, + | DefKind::SyntheticCoroutineBody + | DefKind::TestBinderConstraints => None, } } @@ -345,6 +349,7 @@ impl DefKind { DefKind::Impl { .. } => DefPathData::Impl, DefKind::Closure => DefPathData::Closure, DefKind::SyntheticCoroutineBody => DefPathData::SyntheticCoroutineBody, + DefKind::TestBinderConstraints => DefPathData::TestBinderConstraints, } } @@ -394,7 +399,8 @@ impl DefKind { | DefKind::TraitAlias | DefKind::TyAlias | DefKind::Union - | DefKind::Variant => true, + | DefKind::Variant + | DefKind::TestBinderConstraints => true, DefKind::ConstParam | DefKind::ExternCrate | DefKind::ForeignMod @@ -439,7 +445,8 @@ impl DefKind { | DefKind::LifetimeParam | DefKind::AnonConst | DefKind::GlobalAsm - | DefKind::ExternCrate => false, + | DefKind::ExternCrate + | DefKind::TestBinderConstraints => false, } } } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 37b2ca7718498..a189b82c9e9d3 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -4324,6 +4324,9 @@ impl<'hir> Item<'hir> { ItemKind::TraitAlias(constness, ident, generics, bounds), (*constness, *ident, generics, bounds); expect_impl, &Impl<'hir>, ItemKind::Impl(imp), imp; + + expect_test_binder_constraints, (&'hir Generics<'hir>, &'hir TestBinderBody<'hir>), + ItemKind::TestBinderConstraints { generics, body }, (generics, body); } } @@ -4466,6 +4469,38 @@ impl FnHeader { } } +#[derive(Debug, Clone, Copy, StableHash)] +pub struct TestBinderBody<'hir> { + pub foralls: &'hir [TestBinderForall<'hir>], + pub exists: &'hir [TestBinderExists<'hir>], + pub constraints: TestBinderConstraint<'hir>, +} + +#[derive(Debug, Clone, Copy, StableHash)] +pub struct TestBinderForall<'hir> { + pub span: Span, + pub hir_id: HirId, + pub generics: &'hir Generics<'hir>, + pub body: &'hir TestBinderBody<'hir>, + pub assert_on_exit: Option<&'hir TestBinderConstraint<'hir>>, +} + +#[derive(Debug, Clone, Copy, StableHash)] +pub struct TestBinderExists<'hir> { + pub span: Span, + pub hir_id: HirId, + pub params: &'hir [GenericParam<'hir>], + pub body: &'hir TestBinderBody<'hir>, +} + +#[derive(Debug, Clone, Copy, StableHash)] +pub enum TestBinderConstraint<'hir> { + And { items: &'hir [TestBinderConstraint<'hir>] }, + Or { items: &'hir [TestBinderConstraint<'hir>] }, + Lifetime { lhs: &'hir Lifetime, rhs: &'hir Lifetime }, + Type { lhs: &'hir Ty<'hir>, rhs: &'hir Lifetime }, +} + #[derive(Debug, Clone, Copy, StableHash)] pub enum ItemKind<'hir> { /// An `extern crate` item, with optional *original* crate name if the crate was renamed. @@ -4500,7 +4535,10 @@ pub enum ItemKind<'hir> { /// A module. Mod(Ident, &'hir Mod<'hir>), /// An external module, e.g. `extern { .. }`. - ForeignMod { abi: ExternAbi, items: &'hir [ForeignItemId] }, + ForeignMod { + abi: ExternAbi, + items: &'hir [ForeignItemId], + }, /// Module-level inline assembly (from `global_asm!`). GlobalAsm { asm: &'hir InlineAsm<'hir>, @@ -4535,6 +4573,11 @@ pub enum ItemKind<'hir> { /// An implementation, e.g., `impl Trait for Foo { .. }`. Impl(Impl<'hir>), + + TestBinderConstraints { + generics: &'hir Generics<'hir>, + body: &'hir TestBinderBody<'hir>, + }, } /// Represents an impl block declaration. @@ -4581,7 +4624,8 @@ impl ItemKind<'_> { ItemKind::Use(_, UseKind::Glob | UseKind::ListStem) | ItemKind::ForeignMod { .. } | ItemKind::GlobalAsm { .. } - | ItemKind::Impl(_) => None, + | ItemKind::Impl(_) + | ItemKind::TestBinderConstraints { .. } => None, } } @@ -4595,7 +4639,8 @@ impl ItemKind<'_> { | ItemKind::Union(_, generics, _) | ItemKind::Trait { generics, .. } | ItemKind::TraitAlias(_, _, generics, _) - | ItemKind::Impl(Impl { generics, .. }) => generics, + | ItemKind::Impl(Impl { generics, .. }) + | ItemKind::TestBinderConstraints { generics, .. } => generics, _ => return None, }) } @@ -4869,6 +4914,8 @@ pub enum Node<'hir> { Infer(&'hir InferArg), WherePredicate(&'hir WherePredicate<'hir>), PreciseCapturingNonLifetimeArg(&'hir PreciseCapturingNonLifetimeArg), + TestBinderForall(&'hir TestBinderForall<'hir>), + TestBinderExists(&'hir TestBinderExists<'hir>), // Created by query feeding Synthetic, Err(Span), @@ -4924,6 +4971,8 @@ impl<'hir> Node<'hir> { | Node::OpaqueTy(..) | Node::Infer(..) | Node::WherePredicate(..) + | Node::TestBinderForall(..) + | Node::TestBinderExists(..) | Node::Synthetic | Node::Err(..) => None, } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 3b721392519a7..d176737c0ca40 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -497,6 +497,21 @@ pub trait Visitor<'v>: Sized { fn visit_inline_asm(&mut self, asm: &'v InlineAsm<'v>, id: HirId) -> Self::Result { walk_inline_asm(self, asm, id) } + fn visit_test_binder_body(&mut self, body: &'v TestBinderBody<'v>) -> Self::Result { + walk_test_binder_body(self, body) + } + fn visit_test_binder_forall(&mut self, forall: &'v TestBinderForall<'v>) -> Self::Result { + walk_test_binder_forall(self, forall) + } + fn visit_test_binder_exists(&mut self, exists: &'v TestBinderExists<'v>) -> Self::Result { + walk_test_binder_exists(self, exists) + } + fn visit_test_binder_constraint( + &mut self, + constraint: &'v TestBinderConstraint<'v>, + ) -> Self::Result { + walk_test_binder_constraint(self, constraint) + } } pub trait VisitorExt<'v>: Visitor<'v> { @@ -632,6 +647,10 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: try_visit!(visitor.visit_generics(generics)); walk_list!(visitor, visit_param_bound, bounds); } + ItemKind::TestBinderConstraints { generics, body } => { + try_visit!(visitor.visit_generics(generics)); + try_visit!(visitor.visit_test_binder_body(body)); + } } V::Result::output() } @@ -1559,3 +1578,59 @@ pub fn walk_inline_asm<'v, V: Visitor<'v>>( } V::Result::output() } + +pub fn walk_test_binder_body<'v, V: Visitor<'v>>( + visitor: &mut V, + body: &'v TestBinderBody<'v>, +) -> V::Result { + walk_list!(visitor, visit_test_binder_forall, body.foralls); + walk_list!(visitor, visit_test_binder_exists, body.exists); + try_visit!(visitor.visit_test_binder_constraint(&body.constraints)); + V::Result::output() +} + +pub fn walk_test_binder_forall<'v, V: Visitor<'v>>( + visitor: &mut V, + forall: &'v TestBinderForall<'v>, +) -> V::Result { + try_visit!(visitor.visit_id(forall.hir_id)); + try_visit!(visitor.visit_generics(forall.generics)); + try_visit!(visitor.visit_test_binder_body(forall.body)); + if let Some(assert_on_exit) = &forall.assert_on_exit { + try_visit!(visitor.visit_test_binder_constraint(assert_on_exit)); + } + V::Result::output() +} + +pub fn walk_test_binder_exists<'v, V: Visitor<'v>>( + visitor: &mut V, + exists: &'v TestBinderExists<'v>, +) -> V::Result { + try_visit!(visitor.visit_id(exists.hir_id)); + walk_list!(visitor, visit_generic_param, exists.params); + try_visit!(visitor.visit_test_binder_body(exists.body)); + V::Result::output() +} + +pub fn walk_test_binder_constraint<'v, V: Visitor<'v>>( + visitor: &mut V, + constraint: &'v TestBinderConstraint<'v>, +) -> V::Result { + match constraint { + TestBinderConstraint::And { items } => { + walk_list!(visitor, visit_test_binder_constraint, *items) + } + TestBinderConstraint::Or { items } => { + walk_list!(visitor, visit_test_binder_constraint, *items) + } + TestBinderConstraint::Lifetime { lhs, rhs } => { + try_visit!(visitor.visit_lifetime(lhs)); + try_visit!(visitor.visit_lifetime(rhs)); + } + TestBinderConstraint::Type { lhs, rhs } => { + try_visit!(visitor.visit_ty_unambig(lhs)); + try_visit!(visitor.visit_lifetime(rhs)); + } + } + V::Result::output() +} diff --git a/compiler/rustc_hir/src/target_impls.rs b/compiler/rustc_hir/src/target_impls.rs index ecc9a381c6b6c..d2959cf46fda0 100644 --- a/compiler/rustc_hir/src/target_impls.rs +++ b/compiler/rustc_hir/src/target_impls.rs @@ -91,6 +91,7 @@ impl From<&hir::Item<'_>> for Target { ItemKind::Trait { .. } => Target::Trait, ItemKind::TraitAlias(..) => Target::TraitAlias, ItemKind::Impl(imp_) => Target::Impl { of_trait: imp_.of_trait.is_some() }, + ItemKind::TestBinderConstraints { .. } => Target::MacroCall, } } } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 05328f107fbc8..614d5517ba1f6 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -38,6 +38,7 @@ use crate::check::wfcheck::{ check_associated_item, check_trait_item, check_type_defn, check_variances_for_type_defn, check_where_clauses, enter_wf_checking_ctxt, }; +use crate::collect::ItemCtxt; use crate::diagnostics; fn add_abi_diag_help(abi: ExternAbi, diag: &mut Diag<'_, T>) { @@ -1162,6 +1163,19 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), // avoids this query from having a direct dependency edge on the HIR return res; } + DefKind::TestBinderConstraints => { + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().clauses_of(def_id); + let (_, body) = + tcx.hir_node_by_def_id(def_id).expect_item().expect_test_binder_constraints(); + let icx = ItemCtxt::new(tcx, def_id); + let lowered = icx.lower_test_binder_body(body); + res = res.and(enter_wf_checking_ctxt(tcx, def_id, |wfcx| { + wfcx.check_test_binder_body(lowered); + Ok(()) + })); + return res; + } // These have no wf checks DefKind::AnonConst @@ -1170,7 +1184,16 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), | DefKind::Use | DefKind::GlobalAsm | DefKind::Mod => return res, - _ => {} + + DefKind::ForeignTy => {} + + DefKind::Variant + | DefKind::TyParam + | DefKind::ConstParam + | DefKind::Ctor(..) + | DefKind::Field + | DefKind::LifetimeParam + | DefKind::SyntheticCoroutineBody => unreachable!("{def_id:?}: {:?}", tcx.def_kind(def_id)), } let node = tcx.hir_node_by_def_id(def_id); res.and(match node { diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 0975f066376b2..c932485854398 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -5,6 +5,7 @@ use hir::intravisit::{self, Visitor}; use rustc_abi::{ExternAbi, ScalableElt}; use rustc_ast as ast; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; +use rustc_data_structures::transitive_relation::TransitiveRelationBuilder; use rustc_errors::codes::*; use rustc_errors::{Applicability, ErrorGuaranteed, msg, pluralize, struct_span_code_err}; use rustc_hir as hir; @@ -13,11 +14,11 @@ use rustc_hir::attrs::{EiiDecl, EiiImpl, EiiImplResolution}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{AmbigArg, ItemKind, find_attr}; -use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::outlives::env::OutlivesEnvironment; +use rustc_infer::infer::{BoundRegionConversionTime, SolverRegionConstraint, TyCtxtInferExt}; use rustc_infer::traits::{PredicateObligations, TraitErrors}; use rustc_lint_defs::builtin::{REDUNDANT_LIFETIMES, SHADOWING_SUPERTRAIT_ITEMS}; -use rustc_macros::Diagnostic; +use rustc_macros::{Diagnostic, TypeFoldable, TypeVisitable}; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::traits::solve::NoSolution; use rustc_middle::ty::trait_def::TraitSpecializationKind; @@ -2335,6 +2336,164 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { } } } + + #[instrument(level = "debug", skip(self))] + pub(super) fn check_test_binder_body(&self, body: TestBinderBody<'tcx>) { + let constraints = match validate(self.tcx(), &body.constraints) { + Ok(()) => body.constraints, + Err(_guar) => ty::region_constraint::RegionConstraint::And(Box::new([])), + }; + + self.infcx.register_solver_region_constraint(constraints); + + for forall in body.foralls { + self.check_test_binder_forall(forall); + } + for exists in body.exists { + self.check_test_binder_exists(exists); + } + + fn validate<'tcx>( + tcx: TyCtxt<'tcx>, + constraint: &SolverRegionConstraint<'tcx>, + ) -> Result<(), ErrorGuaranteed> { + match constraint { + ty::region_constraint::RegionConstraint::Ambiguity(_) => Ok(()), + ty::region_constraint::RegionConstraint::RegionOutlives(..) => Ok(()), + ty::region_constraint::RegionConstraint::AliasTyOutlivesViaEnv(..) => Ok(()), + ty::region_constraint::RegionConstraint::PlaceholderTyOutlives(ty, _, span) => { + // we can't check this during lowering, because the ty is a ty::Bound that gets + // instantiated with a placeholder when entering the containing forall. + if let ty::Placeholder(_) | ty::Param(_) = ty.kind() { + Ok(()) + } else { + let mut err = tcx.dcx().struct_span_err( + *span, + "the lhs of a ty outlives must be a placeholder", + ); + err.note(format!("it is a {ty}")); + err.note(format!("and here it is `Debug`ged :3 {ty:?}")); + Err(err.emit()) + } + } + ty::region_constraint::RegionConstraint::And(constraints) => { + let mut res = Ok(()); + for constraint in constraints { + res = res.and(validate(tcx, constraint)); + } + res + } + ty::region_constraint::RegionConstraint::Or(constraints) => { + let mut res = Ok(()); + for constraint in constraints { + res = res.and(validate(tcx, constraint)); + } + res + } + } + } + } + + #[instrument(level = "debug", skip(self))] + fn check_test_binder_forall(&self, forall: TestBinderForall<'tcx>) { + self.infcx.enter_forall(forall.binder, |body| { + let u = self.infcx.universe(); + let mut builder = TransitiveRelationBuilder::default(); + for &(r1, r2) in &body.region_outlives { + builder.add(r1, r2); + } + let assumptions = + ty::region_constraint::Assumptions::new(body.type_outlives, builder.freeze()); + self.infcx.insert_placeholder_assumptions(u, Some(assumptions)); + self.check_test_binder_body(body.value); + let solver_region_constraint = self.infcx.get_solver_region_constraint(); + let constraint = ty::region_constraint::eagerly_handle_placeholders_in_universe( + self.infcx, + solver_region_constraint.without_spans(), + u, + ) + .with_span(forall.span); + if let Some(assert_on_exit) = forall.assert_on_exit { + self.check_test_binder_region_constraints( + forall.span, + &assert_on_exit.clone().canonical_form(), + &constraint.clone().canonical_form(), + ); + } + self.infcx.overwrite_solver_region_constraint(constraint); + }); + } + + #[instrument(level = "debug", skip(self))] + fn check_test_binder_region_constraints( + &self, + fallback_span: Span, + expected: &SolverRegionConstraint<'tcx>, + actual: &SolverRegionConstraint<'tcx>, + ) { + fn span_of<'tcx>(constraint: &SolverRegionConstraint<'tcx>) -> Option { + match constraint { + SolverRegionConstraint::Ambiguity(sp) + | SolverRegionConstraint::RegionOutlives(_, _, sp) + | SolverRegionConstraint::AliasTyOutlivesViaEnv(_, sp) + | ty::region_constraint::RegionConstraint::PlaceholderTyOutlives(_, _, sp) => { + Some(*sp) + } + SolverRegionConstraint::And(constraints) + | SolverRegionConstraint::Or(constraints) => constraints + .iter() + .map(span_of) + .flatten() + .fold(None, |l, r| Some(l.map_or(r, |l| l.to(r)))), + } + } + fn err<'tcx>( + tcx: TyCtxt<'tcx>, + fallback_span: Span, + expected: &SolverRegionConstraint<'tcx>, + actual: &SolverRegionConstraint<'tcx>, + ) { + let mut err = tcx.dcx().struct_span_err( + span_of(expected).unwrap_or(fallback_span), + "forall expect clause failed", + ); + if let Some(actual_span) = span_of(actual) { + err.span_note(actual_span, "constraint from here"); + } + err.note(format!("expected: {expected:?}")); + err.note(format!("actual: {actual:?}")); + err.emit(); + } + match (expected, actual) { + ( + SolverRegionConstraint::And(expected_arr), + SolverRegionConstraint::And(actual_arr), + ) + | (SolverRegionConstraint::Or(expected_arr), SolverRegionConstraint::Or(actual_arr)) => { + if expected_arr.len() != actual_arr.len() { + err(self.tcx(), fallback_span, expected, actual); + } else { + for (expected, actual) in expected_arr.iter().zip(actual_arr) { + self.check_test_binder_region_constraints(fallback_span, expected, actual); + } + } + } + _ if expected.clone().without_spans() != actual.clone().without_spans() => { + err(self.tcx(), fallback_span, expected, actual); + } + _ => (), + } + } + + #[instrument(level = "debug", skip(self))] + fn check_test_binder_exists(&self, exists: TestBinderExists<'tcx>) { + let body = self.infcx.instantiate_binder_with_fresh_vars( + exists.span, + BoundRegionConversionTime::HigherRankedType, + exists.binder, + ); + self.check_test_binder_body(body); + } } pub(super) fn check_type_wf(tcx: TyCtxt<'_>, (): ()) -> Result<(), ErrorGuaranteed> { @@ -2375,7 +2534,8 @@ fn lint_redundant_lifetimes<'tcx>( | DefKind::TraitAlias | DefKind::Fn | DefKind::Const { .. } - | DefKind::Impl { of_trait: _ } => { + | DefKind::Impl { of_trait: _ } + | DefKind::TestBinderConstraints => { // Proceed } DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst { .. } => { @@ -2496,3 +2656,33 @@ struct RedundantLifetimeArgsLint<'tcx> { // The lifetime we can replace the victim with. candidate: ty::Region<'tcx>, } + +#[derive(Clone, Debug, TypeFoldable, TypeVisitable)] +pub(crate) struct TestBinderBody<'tcx> { + pub foralls: Vec>, + pub exists: Vec>, + pub constraints: SolverRegionConstraint<'tcx>, +} + +#[derive(Clone, Debug, TypeFoldable, TypeVisitable)] +pub(crate) struct TestBinderForall<'tcx> { + pub span: Span, + pub binder: ty::Binder<'tcx, WithWhereClauses<'tcx, TestBinderBody<'tcx>>>, + pub assert_on_exit: Option>, +} + +#[derive(Clone, Debug, TypeFoldable, TypeVisitable)] +pub(crate) struct TestBinderExists<'tcx> { + pub span: Span, + pub binder: ty::Binder<'tcx, TestBinderBody<'tcx>>, +} + +#[derive(Clone, Debug, TypeFoldable, TypeVisitable)] +pub(crate) struct WithWhereClauses<'tcx, T> { + pub value: T, + + // The where clauses on the forall. These eventually will probably get stored inside + // `ty::Binder` but they're here for now. + pub type_outlives: Vec>>>, + pub region_outlives: Vec<(ty::Region<'tcx>, ty::Region<'tcx>)>, +} diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index dec24dfd39f22..0b58b42461319 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -28,7 +28,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt}; use rustc_hir::{self as hir, GenericParamKind, HirId, Node, PreciseCapturingArgKind, find_attr}; -use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; +use rustc_infer::infer::{InferCtxt, SolverRegionConstraint, TyCtxtInferExt}; use rustc_infer::traits::{DynCompatibilityViolation, ObligationCause}; use rustc_lint_defs::builtin::REPR_C_ENUMS_LARGER_THAN_INT; use rustc_middle::query::Providers; @@ -46,6 +46,7 @@ use rustc_trait_selection::traits::{ }; use tracing::{debug, instrument}; +use crate::check::wfcheck::{TestBinderBody, TestBinderExists, TestBinderForall}; use crate::diagnostics::{self, ElidedLifetimesAreNotAllowedInDelegations}; use crate::hir_ty_lowering::{HirTyLowerer, InherentAssocCandidate, RegionInferReason}; @@ -319,6 +320,143 @@ impl<'tcx> ItemCtxt<'tcx> { diag.emit() } + + #[instrument(level = "debug", skip(self), ret)] + pub(super) fn lower_test_binder_body( + &self, + item: &hir::TestBinderBody<'tcx>, + ) -> TestBinderBody<'tcx> { + let foralls = + item.foralls.iter().map(|forall| self.lower_test_binder_forall(forall)).collect(); + let exists = + item.exists.iter().map(|exists| self.lower_test_binder_exists(exists)).collect(); + let constraints = self.lower_test_binder_constraint(&item.constraints); + TestBinderBody { foralls, exists, constraints } + } + + #[instrument(level = "debug", skip(self), ret)] + pub(super) fn lower_test_binder_forall( + &self, + forall: &hir::TestBinderForall<'tcx>, + ) -> TestBinderForall<'tcx> { + let bound_vars = self.tcx.late_bound_vars(forall.hir_id); + let value = self.lower_test_binder_body(forall.body); + let mut type_outlives = vec![]; + let mut region_outlives = vec![]; + for predicate in forall.generics.predicates { + self.lower_test_binder_assumptions(predicate, &mut type_outlives, &mut region_outlives); + } + let body = + crate::check::wfcheck::WithWhereClauses { value, type_outlives, region_outlives }; + let binder = ty::Binder::bind_with_vars(body, bound_vars); + let assert_on_exit = forall + .assert_on_exit + .map(|assert_on_exit| self.lower_test_binder_constraint(assert_on_exit)); + TestBinderForall { span: forall.span, binder, assert_on_exit } + } + + #[instrument(level = "debug", skip(self), ret)] + pub(super) fn lower_test_binder_exists( + &self, + exists: &hir::TestBinderExists<'tcx>, + ) -> TestBinderExists<'tcx> { + let bound_vars = self.tcx.late_bound_vars(exists.hir_id); + let body = self.lower_test_binder_body(exists.body); + let binder = ty::Binder::bind_with_vars(body, bound_vars); + TestBinderExists { span: exists.span, binder } + } + + // FIXME: this is likely too basic, and we'll want to evolve/make this more advanced over time. + // For example, right now, if the user writes `forall<'a> where Foo<'a>: 'b`, that's not gonna + // work - that should be destructured into `where 'a: 'b`, whether by hand (and checked it was + // indeed done so, via compiler) or automatically by the test framework, unsure, but something. + fn lower_test_binder_assumptions( + &self, + predicate: &hir::WherePredicate<'tcx>, + type_outlives: &mut Vec>>>, + region_outlives: &mut Vec<(ty::Region<'tcx>, ty::Region<'tcx>)>, + ) { + match predicate.kind { + hir::WherePredicateKind::BoundPredicate(p) => { + let bound_vars = self.tcx.late_bound_vars(predicate.hir_id); + let ty = self.lower_ty(p.bounded_ty); + for bound in p.bounds { + match bound { + hir::GenericBound::Trait(poly_trait_ref) => { + self.dcx() + .span_err(poly_trait_ref.span, "trait bounds aren't supported yet"); + } + hir::GenericBound::Outlives(lifetime) => { + let region = self + .lowerer() + .lower_lifetime(lifetime, RegionInferReason::RegionPredicate); + let binder = ty::Binder::bind_with_vars( + ty::OutlivesClause(ty, region), + bound_vars, + ); + type_outlives.push(binder); + } + hir::GenericBound::Use(_, span) => { + self.dcx().span_err(*span, "use bounds aren't supported yet"); + } + } + } + } + hir::WherePredicateKind::RegionPredicate(predicate) => { + let lhs = self + .lowerer() + .lower_lifetime(predicate.lifetime, RegionInferReason::RegionPredicate); + for bound in predicate.bounds { + match bound { + hir::GenericBound::Trait(poly_trait_ref) => { + self.dcx() + .span_err(poly_trait_ref.span, "trait bounds aren't supported yet"); + } + hir::GenericBound::Outlives(lifetime) => { + let rhs = self + .lowerer() + .lower_lifetime(lifetime, RegionInferReason::RegionPredicate); + region_outlives.push((lhs, rhs)); + } + hir::GenericBound::Use(_, span) => { + self.dcx().span_err(*span, "use bounds aren't supported yet"); + } + } + } + } + } + } + + fn lower_test_binder_constraint( + &self, + constraint: &hir::TestBinderConstraint<'tcx>, + ) -> SolverRegionConstraint<'tcx> { + match constraint { + hir::TestBinderConstraint::And { items } => { + ty::region_constraint::RegionConstraint::And( + items.iter().map(|i| self.lower_test_binder_constraint(i)).collect(), + ) + } + hir::TestBinderConstraint::Or { items } => ty::region_constraint::RegionConstraint::Or( + items.iter().map(|i| self.lower_test_binder_constraint(i)).collect(), + ), + hir::TestBinderConstraint::Lifetime { lhs, rhs } => { + let span = lhs.ident.span.to(rhs.ident.span); + let lhs = self.lowerer().lower_lifetime(lhs, RegionInferReason::RegionPredicate); + let rhs = self.lowerer().lower_lifetime(rhs, RegionInferReason::RegionPredicate); + ty::region_constraint::RegionConstraint::RegionOutlives(lhs, rhs, span) + } + hir::TestBinderConstraint::Type { lhs, rhs } => { + let span = lhs.span.to(rhs.ident.span); + let lhs = self.lower_ty(lhs); + let rhs = self.lowerer().lower_lifetime(rhs, RegionInferReason::RegionPredicate); + // note that we cannot check that lhs is a placeholder at this moment, as at this + // point it is a bound variable that is not yet instantiated with a placeholder. + // instead, we check it when we emit the region constraint. + ty::region_constraint::RegionConstraint::PlaceholderTyOutlives(lhs, rhs, span) + } + } + } } impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index f55833c1bf6da..dbd210e08ea50 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -649,7 +649,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { | hir::ItemKind::Union(_, generics, _) | hir::ItemKind::Trait { generics, .. } | hir::ItemKind::TraitAlias(_, _, generics, ..) - | hir::ItemKind::Impl(hir::Impl { generics, .. }) => { + | hir::ItemKind::Impl(hir::Impl { generics, .. }) + | hir::ItemKind::TestBinderConstraints { generics, .. } => { // These kinds of items have only early-bound lifetime parameters. self.visit_early(item.hir_id(), generics, |this| intravisit::walk_item(this, item)); } @@ -1083,6 +1084,71 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { } } } + + fn visit_test_binder_forall( + &mut self, + forall: &'tcx rustc_hir::TestBinderForall<'tcx>, + ) -> Self::Result { + let (bound_vars, binders): (FxIndexMap, Vec<_>) = forall + .generics + .params + .iter() + .enumerate() + .map(|(late_bound_idx, param)| { + ( + (param.def_id, ResolvedArg::late(late_bound_idx as u32, param)), + late_arg_as_bound_arg(param), + ) + }) + .unzip(); + self.record_late_bound_vars(forall.hir_id, binders); + let scope = Scope::Binder { + hir_id: forall.hir_id, + bound_vars, + s: self.scope, + scope_type: BinderScopeType::Normal, + where_bound_origin: None, + }; + self.with(scope, |this| { + this.visit_generics(forall.generics); + this.visit_test_binder_body(forall.body); + }); + // exit assertions don't have the bound vars in scope + if let Some(assert_on_exit) = forall.assert_on_exit { + self.visit_test_binder_constraint(assert_on_exit); + } + } + + fn visit_test_binder_exists( + &mut self, + exists: &'tcx rustc_hir::TestBinderExists<'tcx>, + ) -> Self::Result { + let (bound_vars, binders): (FxIndexMap, Vec<_>) = exists + .params + .iter() + .enumerate() + .map(|(late_bound_idx, param)| { + ( + (param.def_id, ResolvedArg::late(late_bound_idx as u32, param)), + late_arg_as_bound_arg(param), + ) + }) + .unzip(); + self.record_late_bound_vars(exists.hir_id, binders); + let scope = Scope::Binder { + hir_id: exists.hir_id, + bound_vars, + s: self.scope, + scope_type: BinderScopeType::Normal, + where_bound_origin: None, + }; + self.with(scope, |this| { + for param in exists.params { + this.visit_generic_param(param); + } + this.visit_test_binder_body(exists.body); + }); + } } fn object_lifetime_default(tcx: TyCtxt<'_>, param_def_id: LocalDefId) -> ObjectLifetimeDefault { @@ -1977,7 +2043,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { | DefKind::Static { .. } | DefKind::SyntheticCoroutineBody | DefKind::TyParam - | DefKind::Use => None, // see NOTE above! + | DefKind::Use + | DefKind::TestBinderConstraints => None, // see NOTE above! } } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index da269186f009b..45254aa23896d 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -194,7 +194,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ | ItemKind::Mod(..) | ItemKind::ForeignMod { .. } | ItemKind::ExternCrate(..) - | ItemKind::Use(..) => { + | ItemKind::Use(..) + | ItemKind::TestBinderConstraints { .. } => { span_bug!(item.span, "compute_type_of_item: unexpected item type: {:?}", item.kind); } }, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 92f89c2834408..16a622da61c2b 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -3021,7 +3021,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { | DefKind::Closure | DefKind::ExternCrate | DefKind::GlobalAsm - | DefKind::SyntheticCoroutineBody, + | DefKind::SyntheticCoroutineBody + | DefKind::TestBinderConstraints, _, ) | Res::PrimTy(_) diff --git a/compiler/rustc_hir_id/src/definitions.rs b/compiler/rustc_hir_id/src/definitions.rs index b334efab351bc..50f7a15b19adf 100644 --- a/compiler/rustc_hir_id/src/definitions.rs +++ b/compiler/rustc_hir_id/src/definitions.rs @@ -227,6 +227,7 @@ pub enum DefPathData { LifetimeNs(Symbol), /// A closure expression. Closure, + TestBinderConstraints, // Subportions of items: /// Implicit constructor for a unit or tuple-like struct or enum variant. @@ -447,7 +448,8 @@ impl DefPathData { | OpaqueTy | AnonAssocTy(..) | SyntheticCoroutineBody - | NestedStatic => None, + | NestedStatic + | TestBinderConstraints => None, } } @@ -467,7 +469,8 @@ impl DefPathData { | AnonConst | OpaqueTy | SyntheticCoroutineBody - | NestedStatic => None, + | NestedStatic + | TestBinderConstraints => None, } } @@ -489,6 +492,9 @@ impl DefPathData { AnonAssocTy(..) => DefPathDataName::Anon { namespace: sym::anon_assoc }, SyntheticCoroutineBody => DefPathDataName::Anon { namespace: sym::synthetic }, NestedStatic => DefPathDataName::Anon { namespace: sym::nested }, + TestBinderConstraints => { + DefPathDataName::Anon { namespace: sym::test_binder_constraints } + } } } } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index f2f485a30300a..dae48d2ae55b3 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -216,6 +216,8 @@ impl<'a> State<'a> { Node::LetStmt(a) => self.print_local_decl(a), Node::Crate(..) => panic!("cannot print Crate"), Node::WherePredicate(pred) => self.print_where_predicate(pred), + Node::TestBinderForall(_) => panic!("cannot print Node::TestBinderForall"), + Node::TestBinderExists(_) => panic!("cannot print Node::TestBinderExists"), Node::Synthetic => unreachable!(), Node::Err(_) => self.word("/*ERROR*/"), } @@ -807,6 +809,9 @@ impl<'a> State<'a> { self.end(ib); self.end(cb); } + rustc_hir::ItemKind::TestBinderConstraints { .. } => { + self.word("test_binder_constraints!(/* pretty-printing not supported */)"); + } } self.ann.post(self, AnnNode::Item(item)) } diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index 5eafe73301ba7..e6ddbd879f9b9 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -51,20 +51,20 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { u: ty::UniverseIndex, assumptions: Option>>, ) { - self.placeholder_assumptions_for_next_solver.borrow_mut().insert(u, assumptions); + self.insert_placeholder_assumptions(u, assumptions); } fn get_placeholder_assumptions( &self, u: ty::UniverseIndex, ) -> Option>> { - self.placeholder_assumptions_for_next_solver.borrow().get(&u).unwrap().as_ref().cloned() + self.get_placeholder_assumptions(u) } fn get_solver_region_constraint( &self, ) -> rustc_type_ir::region_constraint::RegionConstraint> { - self.inner.borrow().solver_region_constraint_storage.get_unspanned_constraint() + self.get_solver_region_constraint().without_spans() } fn overwrite_solver_region_constraint( @@ -72,13 +72,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { constraint: rustc_type_ir::region_constraint::RegionConstraint>, span: Span, ) { - let mut inner = self.inner.borrow_mut(); - use rustc_data_structures::undo_log::UndoLogs; - - use crate::infer::UndoLog; - let old_constraint = inner.solver_region_constraint_storage.get_constraint(); - inner.undo_log.push(UndoLog::OverwriteSolverRegionConstraint { old_constraint }); - inner.solver_region_constraint_storage.overwrite(constraint, span); + self.overwrite_solver_region_constraint(constraint.with_span(span)); } fn universe_of_ty(&self, vid: ty::TyVid) -> Option { @@ -334,13 +328,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { c: rustc_type_ir::region_constraint::RegionConstraint>, span: Span, ) { - let mut inner = self.inner.borrow_mut(); - use rustc_data_structures::undo_log::UndoLogs; - - use crate::infer::UndoLog; - let previous_was_and = inner.solver_region_constraint_storage.is_and(); - inner.undo_log.push(UndoLog::PushSolverRegionConstraint { previous_was_and }); - inner.solver_region_constraint_storage.push(c, span); + self.register_solver_region_constraint(c.with_span(span)); } fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>, span: Span) { diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index eed1e42311e65..a49a4355b66b1 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -65,7 +65,7 @@ mod solver_region_constraints; mod type_variable; mod unify_key; -pub(crate) use solver_region_constraints::SolverRegionConstraint; +pub use solver_region_constraints::SolverRegionConstraint; use solver_region_constraints::SolverRegionConstraintStorage; /// `InferOk<'tcx, ()>` is used a lot. It may seem like a useless wrapper @@ -1475,10 +1475,10 @@ impl<'tcx> InferCtxt<'tcx> { value: ty::Binder<'tcx, T>, ) -> T where - T: TypeFoldable> + Copy, + T: TypeFoldable>, { - if let Some(inner) = value.no_bound_vars() { - return inner; + if let Some(_) = value.as_ref().no_bound_vars() { + return value.skip_binder(); } let bound_vars = value.bound_vars(); @@ -1514,6 +1514,48 @@ impl<'tcx> InferCtxt<'tcx> { self.tcx.replace_bound_vars_uncached(value, delegate) } + pub fn insert_placeholder_assumptions( + &self, + u: ty::UniverseIndex, + assumptions: Option>>, + ) { + if let Some(assumptions) = &assumptions { + assert!( + !assumptions.type_outlives.has_escaping_bound_vars(), + "assumptions has escaping bound vars, which is indicative of a bug in how assumptions are handled: {:?}", + assumptions.type_outlives + ); + assert!( + assumptions.region_outlives.base_edges().all(|r| !r.has_escaping_bound_vars()), + "assumptions has escaping bound vars, which is indicative of a bug in how assumptions are handled: {:?}", + assumptions.region_outlives + ); + } + self.placeholder_assumptions_for_next_solver.borrow_mut().insert(u, assumptions); + } + + pub fn get_placeholder_assumptions( + &self, + u: ty::UniverseIndex, + ) -> Option>> { + self.placeholder_assumptions_for_next_solver.borrow().get(&u).unwrap().as_ref().cloned() + } + + pub fn get_solver_region_constraint(&self) -> SolverRegionConstraint<'tcx> { + self.inner.borrow().solver_region_constraint_storage.get_constraint() + } + + pub fn overwrite_solver_region_constraint(&self, constraint: SolverRegionConstraint<'tcx>) { + assert!( + !constraint.has_escaping_bound_vars(), + "solver region constraint has escaping bound vars, which is indicative of a bug in how constraints are handled: {constraint:?}", + ); + let mut inner = self.inner.borrow_mut(); + let old_constraint = inner.solver_region_constraint_storage.get_constraint(); + inner.undo_log.push(UndoLog::OverwriteSolverRegionConstraint { old_constraint }); + inner.solver_region_constraint_storage.overwrite(constraint); + } + /// See the [`region_constraints::RegionConstraintCollector::verify_generic_bound`] method. pub(crate) fn verify_generic_bound( &self, diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 2bf73e5da7e34..a861b89cceb8e 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -77,7 +77,8 @@ use crate::infer::outlives::env::RegionBoundPairs; use crate::infer::outlives::verify::VerifyBoundCx; use crate::infer::snapshot::undo_log::UndoLog; use crate::infer::{ - self, GenericKind, InferCtxt, SubregionOrigin, TypeOutlivesConstraint, VerifyBound, + self, GenericKind, InferCtxt, SolverRegionConstraint, SubregionOrigin, TypeOutlivesConstraint, + VerifyBound, }; use crate::traits::{ObligationCause, ObligationCauseCode}; @@ -139,6 +140,13 @@ impl<'tcx> InferCtxt<'tcx> { inner.region_obligations.push(obligation); } + pub fn register_solver_region_constraint(&self, c: SolverRegionConstraint<'tcx>) { + let mut inner = self.inner.borrow_mut(); + let previous_was_and = inner.solver_region_constraint_storage.is_and(); + inner.undo_log.push(UndoLog::PushSolverRegionConstraint { previous_was_and }); + inner.solver_region_constraint_storage.push(c); + } + pub fn register_type_outlives_constraint( &self, sup_type: Ty<'tcx>, diff --git a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs index 321a7ce4901b4..fe697eb4c01ac 100644 --- a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs +++ b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs @@ -88,7 +88,7 @@ impl<'tcx> Rollback> for InferCtxtInner<'tcx> { ); } UndoLog::OverwriteSolverRegionConstraint { old_constraint } => { - self.solver_region_constraint_storage.overwrite_spanned(old_constraint); + self.solver_region_constraint_storage.overwrite(old_constraint); } UndoLog::PushTypeOutlivesConstraint => { let popped = self.region_obligations.pop(); diff --git a/compiler/rustc_infer/src/infer/solver_region_constraints.rs b/compiler/rustc_infer/src/infer/solver_region_constraints.rs index 885bf53dbe6c2..268c677e0ff19 100644 --- a/compiler/rustc_infer/src/infer/solver_region_constraints.rs +++ b/compiler/rustc_infer/src/infer/solver_region_constraints.rs @@ -1,11 +1,8 @@ use rustc_middle::ty::TyCtxt; -use rustc_span::Span; -use rustc_type_ir::region_constraint::{ - RegionConstraint as UnspannedRegionConstraint, SpannedRegionConstraint, -}; +use rustc_type_ir::region_constraint::SpannedRegionConstraint; use tracing::instrument; -pub(crate) type SolverRegionConstraint<'tcx> = SpannedRegionConstraint>; +pub type SolverRegionConstraint<'tcx> = SpannedRegionConstraint>; #[derive(Clone, Debug)] pub(crate) struct SolverRegionConstraintStorage<'tcx>(SolverRegionConstraint<'tcx>); @@ -19,10 +16,6 @@ impl<'tcx> SolverRegionConstraintStorage<'tcx> { self.0.clone() } - pub(crate) fn get_unspanned_constraint(&self) -> UnspannedRegionConstraint> { - self.0.clone().without_spans() - } - pub(crate) fn is_and(&self) -> bool { self.0.is_and() } @@ -45,8 +38,7 @@ impl<'tcx> SolverRegionConstraintStorage<'tcx> { } #[instrument(level = "debug")] - pub(crate) fn push(&mut self, constraint: UnspannedRegionConstraint>, span: Span) { - let constraint = constraint.with_span(span); + pub(crate) fn push(&mut self, constraint: SolverRegionConstraint<'tcx>) { match core::mem::replace(&mut self.0, SolverRegionConstraint::new_true()) { SolverRegionConstraint::And(and) => { let and = @@ -60,15 +52,7 @@ impl<'tcx> SolverRegionConstraintStorage<'tcx> { } #[instrument(level = "debug", skip(self))] - pub(crate) fn overwrite( - &mut self, - constraint: UnspannedRegionConstraint>, - span: Span, - ) { - self.overwrite_spanned(constraint.with_span(span)); - } - - pub(crate) fn overwrite_spanned(&mut self, constraint: SolverRegionConstraint<'tcx>) { + pub(crate) fn overwrite(&mut self, constraint: SolverRegionConstraint<'tcx>) { self.0 = constraint; } } diff --git a/compiler/rustc_lint/src/types/improper_ctypes.rs b/compiler/rustc_lint/src/types/improper_ctypes.rs index 08dbeec3dcdfd..b37d90e7bdc7f 100644 --- a/compiler/rustc_lint/src/types/improper_ctypes.rs +++ b/compiler/rustc_lint/src/types/improper_ctypes.rs @@ -1257,7 +1257,8 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesLint { | hir::ItemKind::Mod(..) | hir::ItemKind::Macro(..) | hir::ItemKind::Use(..) - | hir::ItemKind::ExternCrate(..) => {} + | hir::ItemKind::ExternCrate(..) + | hir::ItemKind::TestBinderConstraints { .. } => {} } } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index cc7da00fcec5c..1d9dade66a544 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -926,7 +926,7 @@ fn should_encode_span(def_kind: DefKind) -> bool { | DefKind::Impl { .. } | DefKind::Closure | DefKind::SyntheticCoroutineBody => true, - DefKind::ForeignMod | DefKind::GlobalAsm => false, + DefKind::ForeignMod | DefKind::GlobalAsm | DefKind::TestBinderConstraints => false, } } @@ -969,7 +969,8 @@ fn should_encode_attrs(def_kind: DefKind) -> bool { | DefKind::OpaqueTy | DefKind::LifetimeParam | DefKind::Static { nested: true, .. } - | DefKind::GlobalAsm => false, + | DefKind::GlobalAsm + | DefKind::TestBinderConstraints => false, } } @@ -1004,7 +1005,8 @@ fn should_encode_expn_that_defined(def_kind: DefKind) -> bool { | DefKind::LifetimeParam | DefKind::GlobalAsm | DefKind::Closure - | DefKind::SyntheticCoroutineBody => false, + | DefKind::SyntheticCoroutineBody + | DefKind::TestBinderConstraints => false, } } @@ -1040,7 +1042,8 @@ fn should_encode_visibility(def_kind: DefKind) -> bool { | DefKind::Impl { .. } | DefKind::Closure | DefKind::ExternCrate - | DefKind::SyntheticCoroutineBody => false, + | DefKind::SyntheticCoroutineBody + | DefKind::TestBinderConstraints => false, } } @@ -1075,7 +1078,8 @@ fn should_encode_stability(def_kind: DefKind) -> bool { | DefKind::GlobalAsm | DefKind::Closure | DefKind::ExternCrate - | DefKind::SyntheticCoroutineBody => false, + | DefKind::SyntheticCoroutineBody + | DefKind::TestBinderConstraints => false, } } @@ -1165,7 +1169,8 @@ fn should_encode_variances<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, def_kind: Def | DefKind::GlobalAsm | DefKind::Closure | DefKind::ExternCrate - | DefKind::SyntheticCoroutineBody => false, + | DefKind::SyntheticCoroutineBody + | DefKind::TestBinderConstraints => false, } } @@ -1200,7 +1205,8 @@ fn should_encode_generics(def_kind: DefKind) -> bool { | DefKind::Use | DefKind::LifetimeParam | DefKind::GlobalAsm - | DefKind::ExternCrate => false, + | DefKind::ExternCrate + | DefKind::TestBinderConstraints => false, } } @@ -1260,7 +1266,8 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) -> | DefKind::Use | DefKind::LifetimeParam | DefKind::GlobalAsm - | DefKind::ExternCrate => false, + | DefKind::ExternCrate + | DefKind::TestBinderConstraints => false, } } @@ -1295,7 +1302,8 @@ fn should_encode_fn_sig(def_kind: DefKind) -> bool { | DefKind::LifetimeParam | DefKind::GlobalAsm | DefKind::ExternCrate - | DefKind::SyntheticCoroutineBody => false, + | DefKind::SyntheticCoroutineBody + | DefKind::TestBinderConstraints => false, } } @@ -1333,7 +1341,8 @@ fn should_encode_constness(def_kind: DefKind) -> bool { | DefKind::ExternCrate | DefKind::Ctor(_, CtorKind::Const) | DefKind::Variant - | DefKind::SyntheticCoroutineBody => false, + | DefKind::SyntheticCoroutineBody + | DefKind::TestBinderConstraints => false, } } @@ -1368,7 +1377,8 @@ fn should_encode_const(def_kind: DefKind) -> bool { | DefKind::LifetimeParam | DefKind::GlobalAsm | DefKind::ExternCrate - | DefKind::SyntheticCoroutineBody => false, + | DefKind::SyntheticCoroutineBody + | DefKind::TestBinderConstraints => false, } } diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 6f9ec9dbb0d20..c52b22c6f108e 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -202,6 +202,7 @@ fixed_size_enum! { ( Macro(MACRO_KINDS_DERIVE_BANG) ) ( Macro(MACRO_KINDS_DERIVE_ATTR_BANG) ) ( SyntheticCoroutineBody ) + ( TestBinderConstraints ) } unreachable { ( Macro(_) ) } diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index 8ec27921a5787..b384a7a16e54f 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -728,6 +728,7 @@ impl<'tcx> TyCtxt<'tcx> { ItemKind::Trait { .. } => "trait", ItemKind::TraitAlias(..) => "trait alias", ItemKind::Impl { .. } => "impl", + ItemKind::TestBinderConstraints { .. } => "test_binder_constraints!", }; format!("{id} ({item_str} {})", path_str(item.owner_id.def_id)) } @@ -794,9 +795,11 @@ impl<'tcx> TyCtxt<'tcx> { } Node::Crate(..) => String::from("(root_crate)"), Node::WherePredicate(_) => node_str("where predicate"), + Node::PreciseCapturingNonLifetimeArg(_param) => node_str("parameter"), + Node::TestBinderForall(_) => node_str("forall"), + Node::TestBinderExists(_) => node_str("exists"), Node::Synthetic => unreachable!(), Node::Err(_) => node_str("error"), - Node::PreciseCapturingNonLifetimeArg(_param) => node_str("parameter"), } } @@ -1070,6 +1073,8 @@ impl<'tcx> TyCtxt<'tcx> { Node::Crate(item) => item.spans.inner_span, Node::WherePredicate(pred) => pred.span, Node::PreciseCapturingNonLifetimeArg(param) => param.ident.span, + Node::TestBinderForall(forall) => forall.span, + Node::TestBinderExists(exists) => exists.span, Node::Synthetic => unreachable!(), Node::Err(span) => span, } diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 5099859218187..f74f32d44d830 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -350,7 +350,9 @@ impl<'tcx> TyCtxt<'tcx> { | Node::WherePredicate(_) | Node::PreciseCapturingNonLifetimeArg(_) | Node::ConstArgExprField(_) - | Node::OpaqueTy(_) => { + | Node::OpaqueTy(_) + | Node::TestBinderForall(_) + | Node::TestBinderExists(_) => { unreachable!("no sub-expr expected for {parent_node:?}") } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 3dec913ab9481..c4b886110595b 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2408,7 +2408,8 @@ impl<'tcx> TyCtxt<'tcx> { | DefKind::Field | DefKind::LifetimeParam | DefKind::GlobalAsm - | DefKind::SyntheticCoroutineBody => false, + | DefKind::SyntheticCoroutineBody + | DefKind::TestBinderConstraints => false, } } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 054d4e18d3b70..abf667480a3fa 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -679,7 +679,8 @@ impl<'tcx> Ty<'tcx> { | DefKind::GlobalAsm | DefKind::Impl { .. } | DefKind::Closure - | DefKind::SyntheticCoroutineBody => { + | DefKind::SyntheticCoroutineBody + | DefKind::TestBinderConstraints => { bug!("not an adt: {def:?} ({:?})", tcx.def_kind(def.did())) } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index d18882e4649ca..09963dba563ec 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -627,7 +627,8 @@ impl<'tcx> TyCtxt<'tcx> { | DefKind::Field | DefKind::LifetimeParam | DefKind::GlobalAsm - | DefKind::Impl { .. } => false, + | DefKind::Impl { .. } + | DefKind::TestBinderConstraints => false, } } diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index ec9860c0f35bf..d47f8c4c264dd 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -25,7 +25,7 @@ impl<'a> Parser<'a> { /// ```text /// BOUND = LT_BOUND (e.g., `'a`) /// ``` - fn parse_lt_param_bounds(&mut self) -> GenericBounds { + pub(crate) fn parse_lt_param_bounds(&mut self) -> GenericBounds { let mut lifetimes = ThinVec::new(); while self.check_lifetime() { lifetimes.push(ast::GenericBound::Outlives(self.expect_lifetime())); @@ -536,7 +536,9 @@ impl<'a> Parser<'a> { }; match self.parse_ty_where_predicate_kind() { - Ok(pred) => Ok(PredicateKindOrStructBody::PredicateKind(pred)), + Ok(pred) => Ok(PredicateKindOrStructBody::PredicateKind( + ast::WherePredicateKind::BoundPredicate(pred), + )), Err(type_err) => { let Some(((struct_name, body_insertion_point), mut snapshot)) = snapshot else { return Err(type_err); @@ -584,7 +586,9 @@ impl<'a> Parser<'a> { } } - fn parse_ty_where_predicate_kind(&mut self) -> PResult<'a, ast::WherePredicateKind> { + pub(crate) fn parse_ty_where_predicate_kind( + &mut self, + ) -> PResult<'a, ast::WhereBoundPredicate> { // Parse optional `for<'a, 'b>`. // This `for` is parsed greedily and applies to the whole predicate, // the bounded type can have its own `for` applying only to it. @@ -600,11 +604,11 @@ impl<'a> Parser<'a> { // The bounds may be empty; we intentionally accept predicates like `Ty:`. let bounds = self.parse_generic_bounds()?; - return Ok(ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate { + return Ok(ast::WhereBoundPredicate { bound_generic_params: bound_vars, bounded_ty: ty, bounds, - })); + }); } // NOTE: If we ever end up impl'ing and stabilizing equality predicates (#20041), diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 1306f1fcfb1ce..a0645b94fa225 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2608,6 +2608,110 @@ impl<'a> Parser<'a> { } } + /// Parses the contents of a `test_binder_constraints!`. Perma-unstable and for testing only. + pub fn parse_test_binder_constraints(&mut self) -> PResult<'a, Box> { + self.expect_keyword(exp!(Impl))?; + let mut generics = self.parse_generics()?; + generics.where_clause = self.parse_where_clause()?; + let body = self.parse_test_binder_body()?; + Ok(Box::new(TestBinderConstraints { generics, body: Box::new(body) })) + } + + pub fn parse_test_binder_body(&mut self) -> PResult<'a, TestBinderBody> { + let mut foralls = ThinVec::new(); + let mut exists = ThinVec::new(); + let mut constraints = Vec::new(); + self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), |this| { + match this.token.ident() { + Some((Ident { name: sym::forall, .. }, IdentIsRaw::No)) => { + foralls.push(this.parse_test_binder_forall()?) + } + Some((Ident { name: sym::exists, .. }, IdentIsRaw::No)) => { + exists.push(this.parse_test_binder_exists()?) + } + _ => constraints.push(this.parse_test_binder_constraint()?), + } + Ok(()) + })?; + Ok(TestBinderBody { foralls, exists, constraints }) + } + + pub fn parse_test_binder_forall(&mut self) -> PResult<'a, TestBinderForall> { + let span = self.token.span; + self.bump(); + + let mut generics = self.parse_generics()?; + generics.where_clause = self.parse_where_clause()?; + + let body = self.parse_test_binder_body()?; + + let assert_on_exit = if let Some((i, IdentIsRaw::No)) = self.token.ident() + && i.name == sym::expect + { + self.bump(); + let items = self + .parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), |this| { + this.parse_test_binder_constraint() + })? + .0; + Some(items) + } else { + None + }; + + Ok(TestBinderForall { span, node_id: DUMMY_NODE_ID, generics, body, assert_on_exit }) + } + + pub fn parse_test_binder_exists(&mut self) -> PResult<'a, TestBinderExists> { + let span = self.token.span; + self.bump(); + let params = self.parse_generics()?.params; + let body = self.parse_test_binder_body()?; + Ok(TestBinderExists { span, node_id: DUMMY_NODE_ID, params, body }) + } + + pub fn parse_test_binder_constraint(&mut self) -> PResult<'a, TestBinderConstraint> { + match self.token.ident() { + Some((Ident { name: sym::and, .. }, IdentIsRaw::No)) => { + self.bump(); + let items = self + .parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), |this| { + this.parse_test_binder_constraint() + })? + .0; + Ok(TestBinderConstraint::And { items }) + } + Some((Ident { name: sym::or, .. }, IdentIsRaw::No)) => { + self.bump(); + let items = self + .parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), |this| { + this.parse_test_binder_constraint() + })? + .0; + Ok(TestBinderConstraint::Or { items }) + } + _ if self.token.lifetime().is_some() => { + let lhs = self.expect_lifetime(); + self.expect(exp!(Colon))?; + if !self.check_lifetime() { + self.unexpected()?; + } + let rhs = self.expect_lifetime(); + Ok(TestBinderConstraint::Lifetime { lhs, rhs }) + } + _ if self.token.can_begin_type() => { + let lhs = self.parse_ty_for_where_clause()?; + self.expect(exp!(Colon))?; + if !self.check_lifetime() { + self.unexpected()?; + } + let rhs = self.expect_lifetime(); + Ok(TestBinderConstraint::Type { lhs, rhs }) + } + _ => Err(self.dcx().struct_span_err(self.token.span, "unexpected token")), + } + } + fn report_invalid_macro_expansion_item(&self, args: &DelimArgs, path: Option<&Path>) { let span = args.dspan.entire(); let mut err = self.dcx().struct_span_err( diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index e67408a419611..0d7bcdd739e93 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -66,7 +66,8 @@ fn should_explore(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { | DefKind::Field | DefKind::LifetimeParam | DefKind::Closure - | DefKind::SyntheticCoroutineBody => false, + | DefKind::SyntheticCoroutineBody + | DefKind::TestBinderConstraints => false, } } diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs index 87193b73a1a95..6ce8a1fa292a1 100644 --- a/compiler/rustc_passes/src/input_stats.rs +++ b/compiler/rustc_passes/src/input_stats.rs @@ -265,7 +265,8 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { Union, Trait, TraitAlias, - Impl + Impl, + TestBinderConstraints ] ); hir_visit::walk_item(self, i) @@ -589,7 +590,8 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { MacCall, MacroDef, Delegation, - DelegationMac + DelegationMac, + TestBinderConstraints ] ); ast_visit::walk_item(self, i) diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 576c65a58021c..e5f5b67912c75 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -260,7 +260,8 @@ impl<'tcx> ReachableContext<'tcx> { | hir::ItemKind::Struct(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Union(..) - | hir::ItemKind::GlobalAsm { .. } => {} + | hir::ItemKind::GlobalAsm { .. } + | rustc_hir::ItemKind::TestBinderConstraints { .. } => {} } } Node::TraitItem(trait_method) => { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 535b18d6c2fb0..590cf99d1d272 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -581,7 +581,10 @@ impl<'tcx> EmbargoVisitor<'tcx> { let def_kind = self.tcx.def_kind(def_id); match def_kind { // The interface is empty, and no nested items. - DefKind::Use | DefKind::ExternCrate | DefKind::GlobalAsm => {} + DefKind::Use + | DefKind::ExternCrate + | DefKind::GlobalAsm + | DefKind::TestBinderConstraints => {} // The interface is empty, and all nested items are processed by `check_def_id`. DefKind::Mod => {} // Effective visibilities for macros are processed earlier. @@ -822,7 +825,8 @@ impl ReachEverythingInTheInterfaceVisitor<'_, '_> { | DefKind::ExternCrate | DefKind::GlobalAsm | DefKind::ForeignMod - | DefKind::Const { .. } => { + | DefKind::Const { .. } + | DefKind::TestBinderConstraints => { span_bug!( self.tcx().def_span(def_id), "{def_kind:?} unexpectedly reached by `ReachEverythingInTheInterfaceVisitor`" diff --git a/compiler/rustc_public/src/unstable/mod.rs b/compiler/rustc_public/src/unstable/mod.rs index fee72691117fa..46e790becf1ae 100644 --- a/compiler/rustc_public/src/unstable/mod.rs +++ b/compiler/rustc_public/src/unstable/mod.rs @@ -120,7 +120,8 @@ pub(crate) fn new_item_kind(kind: DefKind) -> ItemKind { | DefKind::Field | DefKind::LifetimeParam | DefKind::Impl { .. } - | DefKind::GlobalAsm => { + | DefKind::GlobalAsm + | DefKind::TestBinderConstraints => { unreachable!("Not a valid item kind: {kind:?}"); } DefKind::Closure | DefKind::AssocFn | DefKind::Fn | DefKind::SyntheticCoroutineBody => { diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 8ce95f80633b0..e92cd82b60e55 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -459,7 +459,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { | DefKind::GlobalAsm | DefKind::Closure | DefKind::SyntheticCoroutineBody - | DefKind::Impl { .. }, + | DefKind::Impl { .. } + | DefKind::TestBinderConstraints, _, ) | Res::Local(..) @@ -987,7 +988,8 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { ItemKind::Impl { .. } | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) - | ItemKind::ConstBlock(..) => {} + | ItemKind::ConstBlock(..) + | ItemKind::TestBinderConstraints(..) => {} ItemKind::MacroDef(..) | ItemKind::MacCall(_) | ItemKind::DelegationMac(..) => { unreachable!() diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index a04f2b5421e37..b45a9d1a6ec54 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -213,6 +213,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { return; } ItemKind::DelegationMac(..) => unreachable!(), + ItemKind::TestBinderConstraints(..) => DefKind::TestBinderConstraints, }; self.with_owner( i.id, diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index 7fabc15d00bda..335abe38d9954 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -407,7 +407,8 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> | ast::ItemKind::TraitAlias(..) | ast::ItemKind::ForeignMod(..) | ast::ItemKind::Fn(..) - | ast::ItemKind::Delegation(..) => return, + | ast::ItemKind::Delegation(..) + | ast::ItemKind::TestBinderConstraints(..) => return, } } } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 0e99db1b95cc1..11db4aaeb54fe 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1489,6 +1489,37 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc self.resolve_anon_const(v, AnonConstKind::FieldDefaultValue); } } + + fn visit_test_binder_forall(&mut self, forall: &'ast TestBinderForall) { + self.with_generic_param_rib( + &forall.generics.params, + RibKind::Normal, + forall.node_id, + LifetimeBinderKind::WhereBound, + forall.span, + |this| { + this.visit_generics(&forall.generics); + this.visit_test_binder_body(&forall.body) + }, + ); + // exit assertions don't have the bound vars in scope + if let Some(assert_on_exit) = &forall.assert_on_exit { + for constraint in assert_on_exit { + self.visit_test_binder_constraint(constraint); + } + } + } + + fn visit_test_binder_exists(&mut self, exists: &'ast TestBinderExists) { + self.with_generic_param_rib( + &exists.params, + RibKind::Normal, + exists.node_id, + LifetimeBinderKind::WhereBound, + exists.span, + |this| visit::walk_test_binder_exists(this, exists), + ); + } } impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { @@ -3055,6 +3086,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ItemKind::MacCall(_) | ItemKind::DelegationMac(..) => { panic!("unexpanded macro in resolve!") } + + ItemKind::TestBinderConstraints(constraints) => { + self.resolve_test_binder_constraints(constraints, item.id); + } } } @@ -3547,6 +3582,28 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ); } + fn resolve_test_binder_constraints( + &mut self, + constraints: &'ast TestBinderConstraints, + item_id: NodeId, + ) { + let generics = &constraints.generics; + self.with_generic_param_rib( + &generics.params, + RibKind::Item( + HasGenericParams::Yes(generics.span), + self.r.tcx.def_kind(self.r.current_owner.def_id), + ), + item_id, + LifetimeBinderKind::ImplBlock, + generics.span, + |this| { + this.visit_generics(generics); + this.visit_test_binder_body(&constraints.body); + }, + ); + } + fn resolve_impl_item( &mut self, item: &'ast AssocItem, @@ -5582,27 +5639,19 @@ fn required_generic_args_suggestion(generics: &ast::Generics) -> Option impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, 'ast, '_, '_> { fn visit_item(&mut self, item: &'ast Item) { - match &item.kind { - ItemKind::TyAlias(TyAlias { generics, .. }) - | ItemKind::Const(ConstItem { generics, .. }) - | ItemKind::Fn(Fn { generics, .. }) - | ItemKind::Enum(_, generics, _) - | ItemKind::Struct(_, generics, _) - | ItemKind::Union(_, generics, _) - | ItemKind::Impl(Impl { generics, .. }) - | ItemKind::Trait(Trait { generics, .. }) - | ItemKind::TraitAlias(TraitAlias { generics, .. }) => { - if let ItemKind::Fn(Fn { sig, .. }) = &item.kind { - self.collect_fn_info(&sig.decl, item.id); - } + if let Some(generics) = item.opt_generics() { + let def_id = self.r.owner_def_id(item.id); + let count = generics + .params + .iter() + .filter(|param| matches!(param.kind, ast::GenericParamKind::Lifetime { .. })) + .count(); + self.r.item_generics_num_lifetimes.insert(def_id, count); + } - let def_id = self.r.owner_def_id(item.id); - let count = generics - .params - .iter() - .filter(|param| matches!(param.kind, ast::GenericParamKind::Lifetime { .. })) - .count(); - self.r.item_generics_num_lifetimes.insert(def_id, count); + match &item.kind { + ItemKind::Fn(Fn { sig, .. }) => { + self.collect_fn_info(&sig.decl, item.id); } ItemKind::ForeignMod(ForeignMod { items, .. }) => { @@ -5623,7 +5672,16 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, 'ast, '_, '_> { | ItemKind::MacroDef(..) | ItemKind::GlobalAsm(..) | ItemKind::MacCall(..) - | ItemKind::DelegationMac(..) => {} + | ItemKind::DelegationMac(..) + | ItemKind::TyAlias(..) + | ItemKind::Const(..) + | ItemKind::Enum(..) + | ItemKind::Struct(..) + | ItemKind::Union(..) + | ItemKind::Impl(..) + | ItemKind::Trait(..) + | ItemKind::TraitAlias(..) + | ItemKind::TestBinderConstraints(..) => {} ItemKind::Delegation(..) => { // Delegated functions have lifetimes, their count is not necessarily zero. // But skipping the delegation items here doesn't mean that the count will be considered zero, diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs index 350718b4f077a..e51f571db857c 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs @@ -805,7 +805,8 @@ fn encode_ty_name(tcx: TyCtxt<'_>, def_id: DefId) -> String { | hir::definitions::DefPathData::MacroNs(..) | hir::definitions::DefPathData::OpaqueLifetime(..) | hir::definitions::DefPathData::LifetimeNs(..) - | hir::definitions::DefPathData::AnonAssocTy(..) => { + | hir::definitions::DefPathData::AnonAssocTy(..) + | hir::definitions::DefPathData::TestBinderConstraints => { bug!("encode_ty_name: unexpected `{:?}`", disambiguated_data.data); } }); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 1b9ab1e05fa8e..e8333751d1df8 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -907,6 +907,7 @@ symbols! { exhaustive_integer_patterns, exhaustive_patterns, existential_type, + exists, exp2f16, exp2f32, exp2f64, @@ -1009,6 +1010,7 @@ symbols! { fn_ptr_from_ptr, fn_ptr_trait, fn_static, + forall, forbid, force_target_feature, forget, @@ -2124,6 +2126,7 @@ symbols! { test, test_2018_feature, test_accepted_feature, + test_binder_constraints, test_case, test_incomplete_feature, test_removed_feature, diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 9c80743694ab6..cf08d3e858ec5 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -971,7 +971,8 @@ impl<'tcx> Printer<'tcx> for V0SymbolMangler<'tcx> { | DefPathData::MacroNs(_) | DefPathData::LifetimeNs(_) | DefPathData::OpaqueLifetime(_) - | DefPathData::AnonAssocTy(..) => { + | DefPathData::AnonAssocTy(..) + | DefPathData::TestBinderConstraints => { bug!("symbol_names: unexpected DefPathData: {:?}", disambiguated_data.data) } }; diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 06c45fb539f63..3653b6ee3670d 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -135,7 +135,8 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' | DefKind::Enum | DefKind::Trait | DefKind::TraitAlias - | DefKind::TyAlias => ty::List::empty(), + | DefKind::TyAlias + | DefKind::TestBinderConstraints => ty::List::empty(), DefKind::OpaqueTy | DefKind::Mod | DefKind::Variant diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 6dc23c45c5144..92a104af7f85b 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -366,7 +366,8 @@ fn opaque_types_defined_by<'tcx>( | DefKind::ForeignMod | DefKind::Field | DefKind::LifetimeParam - | DefKind::Impl { .. } => { + | DefKind::Impl { .. } + | DefKind::TestBinderConstraints => { span_bug!( tcx.def_span(item), "`opaque_types_defined_by` not defined for {} `{item:?}`", diff --git a/compiler/rustc_ty_walk/src/lib.rs b/compiler/rustc_ty_walk/src/lib.rs index ae3cf23809da0..b1597eab2554b 100644 --- a/compiler/rustc_ty_walk/src/lib.rs +++ b/compiler/rustc_ty_walk/src/lib.rs @@ -153,7 +153,8 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( | DefKind::Macro(_) | DefKind::GlobalAsm | DefKind::Mod - | DefKind::Use => {} + | DefKind::Use + | DefKind::TestBinderConstraints => {} } V::Result::output() } diff --git a/library/core/src/internal_macros.rs b/library/core/src/internal_macros.rs index 0d0ff23fe2946..ba75f00791923 100644 --- a/library/core/src/internal_macros.rs +++ b/library/core/src/internal_macros.rs @@ -108,3 +108,13 @@ macro_rules! impl_fn_for_zst { )+ } } + +/// Permanently unstable. Only used in internal rustc tests. Do not use. +#[rustc_builtin_macro(test_binder_constraints)] +#[unstable(feature = "test_binder_constraints", issue = "none")] +#[macro_export] +macro_rules! test_binder_constraints { + ($($arg:tt)*) => { + /* compiler built-in */ + }; +} diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs index e7d7cc2104b17..ed8804281334f 100644 --- a/src/librustdoc/formats/item_type.rs +++ b/src/librustdoc/formats/item_type.rs @@ -197,7 +197,8 @@ impl ItemType { | DefKind::GlobalAsm | DefKind::Impl { .. } | DefKind::Closure - | DefKind::SyntheticCoroutineBody => Self::ForeignType, + | DefKind::SyntheticCoroutineBody + | DefKind::TestBinderConstraints => Self::ForeignType, } } diff --git a/src/librustdoc/html/span_map.rs b/src/librustdoc/html/span_map.rs index 6b187a63c679c..c18975b6a3c4e 100644 --- a/src/librustdoc/html/span_map.rs +++ b/src/librustdoc/html/span_map.rs @@ -366,6 +366,7 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> { | ItemKind::ExternCrate(..) | ItemKind::ForeignMod { .. } | ItemKind::GlobalAsm { .. } + | ItemKind::TestBinderConstraints { .. } // We already have "visit_mod" above so no need to check it here. | ItemKind::Mod(..) => {} } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 38d285f4fe86d..dfc942b6f226d 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -2223,7 +2223,10 @@ fn resolution_failure( | TraitAlias | TyParam | Static { .. } => "associated item", - Impl { .. } | GlobalAsm | SyntheticCoroutineBody => { + Impl { .. } + | GlobalAsm + | SyntheticCoroutineBody + | TestBinderConstraints => { unreachable!("not a path") } } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index d0b02c20644fe..ae5a76545eefb 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -582,6 +582,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { self.add_impl_to_current_mod(item, impl_); } } + hir::ItemKind::TestBinderConstraints { .. } => {} } } diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md index a782f4aca6c53..f323d7040d260 100644 --- a/src/tools/clippy/book/src/lint_configuration.md +++ b/src/tools/clippy/book/src/lint_configuration.md @@ -907,7 +907,7 @@ crate. For example, `pub(crate)` items. ## `module-item-order-groupings` The named groupings of different source item kinds within modules. -**Default Value:** `[["modules", ["extern_crate", "mod", "foreign_mod"]], ["use", ["use"]], ["macros", ["macro"]], ["global_asm", ["global_asm"]], ["UPPER_SNAKE_CASE", ["static", "const"]], ["PascalCase", ["ty_alias", "enum", "struct", "union", "trait", "trait_alias", "impl"]], ["lower_snake_case", ["fn"]]]` +**Default Value:** `[["modules", ["extern_crate", "mod", "foreign_mod"]], ["use", ["use"]], ["macros", ["macro"]], ["global_asm", ["global_asm"]], ["UPPER_SNAKE_CASE", ["static", "const"]], ["PascalCase", ["ty_alias", "enum", "struct", "union", "trait", "trait_alias", "impl", "test_binder_constraints"]], ["lower_snake_case", ["fn"]]]` --- **Affected lints:** diff --git a/src/tools/clippy/clippy_config/src/types.rs b/src/tools/clippy/clippy_config/src/types.rs index 4dc2549c6e233..fd602e4ca5b25 100644 --- a/src/tools/clippy/clippy_config/src/types.rs +++ b/src/tools/clippy/clippy_config/src/types.rs @@ -459,6 +459,7 @@ conf_enum! { TraitAlias("trait_alias"), Impl("impl"), Fn("fn"), + TestBinderConstraints("test_binder_constraints"), } } @@ -483,6 +484,7 @@ impl SourceItemOrderingModuleItemKind { TraitAlias, Impl, Fn, + TestBinderConstraints, ] } } @@ -648,6 +650,7 @@ impl FromDefault<()> for SourceItemOrderingModuleItemGroupings { SourceItemOrderingModuleItemKind::Trait, SourceItemOrderingModuleItemKind::TraitAlias, SourceItemOrderingModuleItemKind::Impl, + SourceItemOrderingModuleItemKind::TestBinderConstraints, ], ), ("lower_snake_case".into(), vec![SourceItemOrderingModuleItemKind::Fn]), @@ -668,6 +671,7 @@ impl FromDefault<()> for SourceItemOrderingModuleItemGroupings { (SourceItemOrderingModuleItemKind::Trait, 5), (SourceItemOrderingModuleItemKind::TraitAlias, 5), (SourceItemOrderingModuleItemKind::Impl, 5), + (SourceItemOrderingModuleItemKind::TestBinderConstraints, 5), (SourceItemOrderingModuleItemKind::Fn, 6), ]), back_lut: HashMap::from_iter([ @@ -686,12 +690,16 @@ impl FromDefault<()> for SourceItemOrderingModuleItemGroupings { (SourceItemOrderingModuleItemKind::Trait, "PascalCase".into()), (SourceItemOrderingModuleItemKind::TraitAlias, "PascalCase".into()), (SourceItemOrderingModuleItemKind::Impl, "PascalCase".into()), + ( + SourceItemOrderingModuleItemKind::TestBinderConstraints, + "PascalCase".into(), + ), (SourceItemOrderingModuleItemKind::Fn, "lower_snake_case".into()), ]), } } fn display_default((): ()) -> impl Display { - r#"[["modules", ["extern_crate", "mod", "foreign_mod"]], ["use", ["use"]], ["macros", ["macro"]], ["global_asm", ["global_asm"]], ["UPPER_SNAKE_CASE", ["static", "const"]], ["PascalCase", ["ty_alias", "enum", "struct", "union", "trait", "trait_alias", "impl"]], ["lower_snake_case", ["fn"]]]"# + r#"[["modules", ["extern_crate", "mod", "foreign_mod"]], ["use", ["use"]], ["macros", ["macro"]], ["global_asm", ["global_asm"]], ["UPPER_SNAKE_CASE", ["static", "const"]], ["PascalCase", ["ty_alias", "enum", "struct", "union", "trait", "trait_alias", "impl", "test_binder_constraints"]], ["lower_snake_case", ["fn"]]]"# } } impl DeserializeOrDefault<()> for SourceItemOrderingModuleItemGroupings { diff --git a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs index 73b63697d844d..65ef6f63e9777 100644 --- a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs +++ b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs @@ -630,6 +630,7 @@ fn convert_module_item_kind(value: &ItemKind<'_>) -> SourceItemOrderingModuleIte ItemKind::Trait { .. } => Trait, ItemKind::TraitAlias(..) => TraitAlias, ItemKind::Impl(..) => Impl, + ItemKind::TestBinderConstraints { .. } => TestBinderConstraints, } } diff --git a/src/tools/clippy/clippy_lints/src/definition_in_module_root.rs b/src/tools/clippy/clippy_lints/src/definition_in_module_root.rs index 14c440abfd982..035f2160de21a 100644 --- a/src/tools/clippy/clippy_lints/src/definition_in_module_root.rs +++ b/src/tools/clippy/clippy_lints/src/definition_in_module_root.rs @@ -139,7 +139,8 @@ fn definition_kind(item: &ast::Item) -> Option<&'static str> { | ItemKind::MacCall(..) | ItemKind::MacroDef(..) | ItemKind::Delegation(..) - | ItemKind::DelegationMac(..) => None, + | ItemKind::DelegationMac(..) + | ItemKind::TestBinderConstraints(..) => None, } } diff --git a/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs b/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs index a78faf0be976a..8c604aadc811e 100644 --- a/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs +++ b/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs @@ -533,7 +533,11 @@ impl LateLintPass<'_> for ItemNameRepetitions { | ItemKind::Union(ident, ..) | ItemKind::Use(_, UseKind::Single(ident)) => ident, - ItemKind::ForeignMod { .. } | ItemKind::GlobalAsm { .. } | ItemKind::Impl(_) | ItemKind::Use(..) => return, + ItemKind::ForeignMod { .. } + | ItemKind::GlobalAsm { .. } + | ItemKind::Impl(_) + | ItemKind::Use(..) + | ItemKind::TestBinderConstraints { .. } => return, }; let item_name = ident.name.as_str(); diff --git a/src/tools/clippy/clippy_lints/src/manual_float_methods.rs b/src/tools/clippy/clippy_lints/src/manual_float_methods.rs index 3835950043492..5e1d12179aacd 100644 --- a/src/tools/clippy/clippy_lints/src/manual_float_methods.rs +++ b/src/tools/clippy/clippy_lints/src/manual_float_methods.rs @@ -118,7 +118,8 @@ fn is_not_const(tcx: TyCtxt<'_>, def_id: DefId) -> bool { | DefKind::Impl { .. } | DefKind::OpaqueTy | DefKind::SyntheticCoroutineBody - | DefKind::TyParam => true, + | DefKind::TyParam + | DefKind::TestBinderConstraints => true, DefKind::AnonConst | DefKind::Const { .. } diff --git a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs index 28fd8b33b7103..e5a292806259d 100644 --- a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs +++ b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs @@ -142,7 +142,8 @@ impl LateLintPass<'_> for MinIdentChars { | ItemKind::ForeignMod { .. } | ItemKind::GlobalAsm { .. } | ItemKind::Impl(_) - | ItemKind::Use(..) => return, + | ItemKind::Use(..) + | ItemKind::TestBinderConstraints { .. } => return, }; if let Some(missing) = self.check_sym(ident.name) && !(matches!(i.kind, ItemKind::Fn { .. }) diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index 30d88207b8637..51423b9811fcb 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -140,7 +140,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { ItemKind::ExternCrate(..) | ItemKind::ForeignMod { .. } | ItemKind::GlobalAsm { .. } - | ItemKind::Use(..) => return, + | ItemKind::Use(..) + | ItemKind::TestBinderConstraints { .. } => return, ItemKind::Mod(ident, ..) => { if item.span.from_expansion() && item.span.eq_ctxt(ident.span) { diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs index 9f69c74596d50..635edb7ada2b2 100644 --- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs +++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs @@ -288,6 +288,7 @@ fn item_search_pat(item: &Item<'_>) -> (Pat, Pat) { ItemKind::TraitAlias(..) => (Pat::Str("trait"), Pat::Str(";")), ItemKind::GlobalAsm { .. } => return (Pat::Str("global_asm"), Pat::Str("")), ItemKind::Use(..) => return (Pat::Str(""), Pat::Str("")), + ItemKind::TestBinderConstraints { .. } => return (Pat::Str(""), Pat::Str("")), }; if item.vis_span.is_empty() { (start_pat, end_pat) diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 8b47c79aa6da2..6bad94d239157 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -2789,7 +2789,9 @@ pub fn expr_use_sites<'tcx>( | Node::TraitRef(_) | Node::Ty(_) | Node::TyPat(_) - | Node::WherePredicate(_) => { + | Node::WherePredicate(_) + | Node::TestBinderForall(_) + | Node::TestBinderExists(_) => { // This shouldn't be possible to hit; the inner iterator should have // been moved to the end before we hit any of these nodes. debug_assert!(false, "found {parent:?} which is after the final use node"); diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/default_exp/clippy.toml b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/default_exp/clippy.toml index af3aa1cc62a49..8d02935ea2de0 100644 --- a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/default_exp/clippy.toml +++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/default_exp/clippy.toml @@ -6,7 +6,7 @@ module-item-order-groupings = [ ["macros", ["macro"]], ["global_asm", ["global_asm"]], ["UPPER_SNAKE_CASE", ["static", "const"]], - ["PascalCase", ["ty_alias", "enum", "struct", "union", "trait", "trait_alias", "impl"]], + ["PascalCase", ["ty_alias", "enum", "struct", "union", "trait", "trait_alias", "impl", "test_binder_constraints"]], ["lower_snake_case", ["fn"]] ] module-items-ordered-within-groupings = "none" diff --git a/src/tools/rustfmt/src/visitor.rs b/src/tools/rustfmt/src/visitor.rs index 55f9a4d8c8b26..b3ba0f2df2cdb 100644 --- a/src/tools/rustfmt/src/visitor.rs +++ b/src/tools/rustfmt/src/visitor.rs @@ -631,6 +631,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { // For now, leave the contents of the Span unformatted. self.push_rewrite(item.span, None) } + ast::ItemKind::TestBinderConstraints(..) => self.push_rewrite(item.span, None), }; } self.skip_context = skip_context_saved; diff --git a/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs b/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs new file mode 100644 index 0000000000000..c02f3bace5071 --- /dev/null +++ b/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs @@ -0,0 +1,70 @@ +//@ compile-flags: -Zassumptions-on-binders +#![feature(test_binder_constraints)] +#![expect(incomplete_features)] + +core::test_binder_constraints! { + impl<'a, 'b> { + 'a: 'b + //~^ ERROR higher-ranked lifetime bound could not be satisfied + } +} + +core::test_binder_constraints! { + impl { + and { + forall { } + //~^ ERROR expected one of + } + } +} + +core::test_binder_constraints! { + impl { + or { + forall { } + //~^ ERROR expected one of + } + } +} + +trait Trait<'a> {} + +core::test_binder_constraints! { + impl<'a> { + dyn for<'b> Trait<'b>: 'a, + //~^ ERROR the lhs of a ty outlives must be a placeholder + } +} + +core::test_binder_constraints! { + impl<'a, T> { + T: for<'b> Trait<'b>, + //~^ ERROR expected lifetime, found keyword `for` + } +} + +core::test_binder_constraints! { + impl<'a> { + forall where T: 'a { + //~^ ERROR only lifetime parameters can be used in this context + T: 'a, + //~^ ERROR the lhs of a ty outlives must be a placeholder + } + } +} + +core::test_binder_constraints! { + impl<'b, 'c: 'b + 'static> { + forall<'a> where 'b: 'a { + 'c: 'a + } expect { + or { + 'c: 'b, + 'c: 'c, + //~^ ERROR forall expect clause failed + } + } + } +} + +fn main() {} diff --git a/tests/ui/assumptions_on_binders/test-infra-fails-properly.stderr b/tests/ui/assumptions_on_binders/test-infra-fails-properly.stderr new file mode 100644 index 0000000000000..0572944204787 --- /dev/null +++ b/tests/ui/assumptions_on_binders/test-infra-fails-properly.stderr @@ -0,0 +1,69 @@ +error: expected one of `!`, `(`, `+`, `::`, `:`, or `<`, found `{` + --> $DIR/test-infra-fails-properly.rs:15:20 + | +LL | forall { } + | ^ expected one of `!`, `(`, `+`, `::`, `:`, or `<` + +error: expected one of `!`, `(`, `+`, `::`, `:`, or `<`, found `{` + --> $DIR/test-infra-fails-properly.rs:24:20 + | +LL | forall { } + | ^ expected one of `!`, `(`, `+`, `::`, `:`, or `<` + +error: expected lifetime, found keyword `for` + --> $DIR/test-infra-fails-properly.rs:41:12 + | +LL | T: for<'b> Trait<'b>, + | ^^^ expected lifetime + +error[E0658]: only lifetime parameters can be used in this context + --> $DIR/test-infra-fails-properly.rs:48:16 + | +LL | forall where T: 'a { + | ^ + | + = note: see issue #108185 for more information + = help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: higher-ranked lifetime bound could not be satisfied + --> $DIR/test-infra-fails-properly.rs:7:9 + | +LL | 'a: 'b + | ^^^^^^ + +error: the lhs of a ty outlives must be a placeholder + --> $DIR/test-infra-fails-properly.rs:34:9 + | +LL | dyn for<'b> Trait<'b>: 'a, + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: it is a (dyn for<'b> Trait<'b> + 'static) + = note: and here it is `Debug`ged :3 dyn [Binder { value: Trait(Trait<'b>), bound_vars: [Region(BrNamed(DefId(0:11 ~ test_infra_fails_properly[2377]::{test_binder_constraints#1}::'b)))] }] + 'static + +error: the lhs of a ty outlives must be a placeholder + --> $DIR/test-infra-fails-properly.rs:50:13 + | +LL | T: 'a, + | ^^^^^ + | + = note: it is a {type error} + = note: and here it is `Debug`ged :3 {type error} + +error: forall expect clause failed + --> $DIR/test-infra-fails-properly.rs:63:17 + | +LL | 'c: 'c, + | ^^^^^^ + | +note: constraint from here + --> $DIR/test-infra-fails-properly.rs:58:9 + | +LL | forall<'a> where 'b: 'a { + | ^^^^^^ + = note: expected: RegionOutlives('c/#1, 'c/#1, $DIR/test-infra-fails-properly.rs:63:17: 63:23 (#0)) + = note: actual: RegionOutlives('c/#1, 'static, $DIR/test-infra-fails-properly.rs:58:9: 58:15 (#0)) + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/assumptions_on_binders/test-infra-works.rs b/tests/ui/assumptions_on_binders/test-infra-works.rs new file mode 100644 index 0000000000000..f172a112fdd43 --- /dev/null +++ b/tests/ui/assumptions_on_binders/test-infra-works.rs @@ -0,0 +1,44 @@ +//@ check-pass +//@ compile-flags: -Zassumptions-on-binders + +#![feature(test_binder_constraints, non_lifetime_binders)] +#![expect(incomplete_features)] + +core::test_binder_constraints! { + impl<'a: 'b, 'b> { + 'a: 'b + } +} + +core::test_binder_constraints! { + impl<'a: 'b, 'b> { + 'a: 'b, + forall { } + } +} + +// FIXME(-Zassumptions-on-binders): this should be `impl<'b, 'c: 'b>`, not +// `impl<'b, 'c: 'b + 'static>`, but OR isn't actually implemented yet +core::test_binder_constraints! { + impl<'b, 'c: 'b + 'static> { + forall<'a> where 'b: 'a { + 'c: 'a + } expect { + or { + 'c: 'b, + 'c: 'static, + } + } + } +} + +core::test_binder_constraints! { + impl<'a, T: 'a> { + T: 'a, + forall where T2: 'a { + T2: 'a, + } + } +} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-test-binder-constraints.rs b/tests/ui/feature-gates/feature-gate-test-binder-constraints.rs new file mode 100644 index 0000000000000..3b79a90a4eb8f --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-test-binder-constraints.rs @@ -0,0 +1,8 @@ +core::test_binder_constraints! { + //~^ ERROR use of unstable library feature + impl<'a: 'b, 'b> { + 'a: 'b + } +} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-test-binder-constraints.stderr b/tests/ui/feature-gates/feature-gate-test-binder-constraints.stderr new file mode 100644 index 0000000000000..d1563bec4e198 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-test-binder-constraints.stderr @@ -0,0 +1,12 @@ +error[E0658]: use of unstable library feature `test_binder_constraints` + --> $DIR/feature-gate-test-binder-constraints.rs:1:1 + | +LL | core::test_binder_constraints! { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(test_binder_constraints)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. From d9d27f8d88f24843a20be5303382c453df2631c1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 24 Aug 2026 09:38:42 +0200 Subject: [PATCH 12/54] unify shim_sig and shim_sig_variadic macros --- src/tools/miri/src/shims/sig.rs | 59 ++++++++++--------- .../miri/src/shims/unix/foreign_items.rs | 8 +-- .../src/shims/unix/linux/foreign_items.rs | 4 +- .../miri/src/shims/unix/linux_like/syscall.rs | 2 +- .../miri/src/shims/unix/linux_like/thread.rs | 2 +- 5 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/tools/miri/src/shims/sig.rs b/src/tools/miri/src/shims/sig.rs index 0a0f84eadadec..ca18bcb79fe0b 100644 --- a/src/tools/miri/src/shims/sig.rs +++ b/src/tools/miri/src/shims/sig.rs @@ -30,26 +30,15 @@ pub struct ShimSig<'tcx, const ARGS: usize> { #[macro_export] macro_rules! shim_sig { (extern $abi:literal fn($($args:tt)*) -> $($ret:tt)*) => { - |this| $crate::shims::sig::ShimSig { - abi: std::str::FromStr::from_str($abi).expect("incorrect abi specified"), - args: shim_sig_args_sep!(this, [$($args)*]), - ret: shim_sig_arg!(this, $($ret)*), - nounwind: false, - c_variadic: false, - } - }; -} - -/// Same as `shim_sig!` but declares a variadic function. The signature is for the fixed part. -#[macro_export] -macro_rules! shim_sig_variadic { - (extern $abi:literal fn($($args:tt)*) -> $($ret:tt)*) => { - |this| $crate::shims::sig::ShimSig { - abi: std::str::FromStr::from_str($abi).expect("incorrect abi specified"), - args: shim_sig_args_sep!(this, [$($args)*]), - ret: shim_sig_arg!(this, $($ret)*), - nounwind: true, - c_variadic: true, + |this| { + let (args, c_variadic) = shim_sig_args_sep!(this, [$($args)*]); + $crate::shims::sig::ShimSig { + abi: std::str::FromStr::from_str($abi).expect("incorrect abi specified"), + args, + ret: shim_sig_arg!(this, $($ret)*), + nounwind: false, + c_variadic, + } } }; } @@ -58,12 +47,15 @@ macro_rules! shim_sig_variadic { #[macro_export] macro_rules! shim_sig_nounwind { (extern $abi:literal fn($($args:tt)*) -> $($ret:tt)*) => { - |this| $crate::shims::sig::ShimSig { - abi: std::str::FromStr::from_str($abi).expect("incorrect abi specified"), - args: shim_sig_args_sep!(this, [$($args)*]), - ret: shim_sig_arg!(this, $($ret)*), - nounwind: true, - c_variadic: false, + |this| { + let (args, c_variadic) = shim_sig_args_sep!(this, [$($args)*]); + $crate::shims::sig::ShimSig { + abi: std::str::FromStr::from_str($abi).expect("incorrect abi specified"), + args, + ret: shim_sig_arg!(this, $($ret)*), + nounwind: true, + c_variadic, + } } }; } @@ -72,13 +64,18 @@ macro_rules! shim_sig_nounwind { #[macro_export] macro_rules! shim_varargs { ($($args:tt)*) => { - |this| shim_sig_args_sep!(this, [$($args)*]) + |this| { + let (args, c_variadic) = shim_sig_args_sep!(this, [$($args)*]); + assert!(!c_variadic); // don't accept `...` here + args + } }; } /// Helper for `shim_sig!`. /// /// Groups tokens into comma-separated chunks and calls the provided macro on them. +/// Returns a list of types and a boolean indicating whether there was a trailing `...`. /// /// # Examples /// @@ -107,13 +104,17 @@ macro_rules! shim_sig_args_sep { (@ $this:ident [$($final:tt)*] [$($collected:tt)*] $first:tt $($tt:tt)*) => { shim_sig_args_sep!(@ $this [$($final)*] [$($collected)* $first] $($tt)*) }; + // No more tokens, trailing `...` - emit final output, indicate this is variadic. + (@ $this:ident [$($final:tt)*] [...] ) => { + ([$($final)*], true) + }; // No more tokens - emit final output, including final non-comma type. (@ $this:ident [$($final:tt)*] [$($collected:tt)+] ) => { - [$($final)* shim_sig_arg!($this, $($collected)*)] + ([$($final)* shim_sig_arg!($this, $($collected)*)], false) }; // No more tokens, empty collector - emit final output. (@ $this:ident [$($final:tt)*] [] ) => { - [$($final)*] + ([$($final)*], false) }; } diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index f8d0641e42db5..503f4b815b508 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -286,7 +286,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "fcntl" => { let ([fd_num, cmd], varargs) = this.check_shim_sig_variadic( - shim_sig_variadic!(extern "C" fn(i32, i32) -> i32), + shim_sig!(extern "C" fn(i32, i32, ...) -> i32), (link_name, abi, args), )?; let result = this.fcntl(fd_num, cmd, varargs)?; @@ -335,9 +335,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { }; let ([fd, op], varargs) = this.check_shim_sig_variadic( if op_is_ulong { - shim_sig_variadic!(extern "C" fn(i32, usize) -> i32) + shim_sig!(extern "C" fn(i32, usize, ...) -> i32) } else { - shim_sig_variadic!(extern "C" fn(i32, i32) -> i32) + shim_sig!(extern "C" fn(i32, i32, ...) -> i32) }, (link_name, abi, args), )?; @@ -350,7 +350,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `open` is variadic, the third argument is only present when the second argument // has O_CREAT (or on linux O_TMPFILE, but miri doesn't support that) set let ([path_raw, flag], varargs) = this.check_shim_sig_variadic( - shim_sig_variadic!(extern "C" fn(*_, i32) -> i32), + shim_sig!(extern "C" fn(*_, i32, ...) -> i32), (link_name, abi, args), )?; let result = this.open(path_raw, flag, varargs)?; diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs index 79134ec9a5058..4ae8e4345063d 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -41,7 +41,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `open64` is variadic, the third argument is only present when the second argument // has O_CREAT (or on linux O_TMPFILE, but miri doesn't support that) set let ([path_raw, flag], varargs) = this.check_shim_sig_variadic( - shim_sig_variadic!(extern "C" fn(*_, i32) -> i32), + shim_sig!(extern "C" fn(*_, i32, ...) -> i32), (link_name, abi, args), )?; let result = this.open(path_raw, flag, varargs)?; @@ -242,7 +242,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "mremap" => { let ([old_address, old_size, new_size, flags], _) = this.check_shim_sig_variadic( - shim_sig_variadic!(extern "C" fn(*_, usize, usize, i32) -> *_), + shim_sig!(extern "C" fn(*_, usize, usize, i32, ...) -> *_), (link_name, abi, args), )?; let ptr = this.mremap(old_address, old_size, new_size, flags)?; diff --git a/src/tools/miri/src/shims/unix/linux_like/syscall.rs b/src/tools/miri/src/shims/unix/linux_like/syscall.rs index 34a84dc60da73..ae9b332657463 100644 --- a/src/tools/miri/src/shims/unix/linux_like/syscall.rs +++ b/src/tools/miri/src/shims/unix/linux_like/syscall.rs @@ -16,7 +16,7 @@ pub fn syscall<'tcx>( dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx> { let ([op], varargs) = ecx.check_shim_sig_variadic( - shim_sig_variadic!(extern "C" fn(isize) -> isize), + shim_sig!(extern "C" fn(isize, ...) -> isize), (link_name, abi, args), )?; // The syscall variadic function is legal to call with more arguments than needed, diff --git a/src/tools/miri/src/shims/unix/linux_like/thread.rs b/src/tools/miri/src/shims/unix/linux_like/thread.rs index 5e275daf81d15..8ddf122af654f 100644 --- a/src/tools/miri/src/shims/unix/linux_like/thread.rs +++ b/src/tools/miri/src/shims/unix/linux_like/thread.rs @@ -16,7 +16,7 @@ pub fn prctl<'tcx>( dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx> { let ([op], varargs) = ecx.check_shim_sig_variadic( - shim_sig_variadic!(extern "C" fn(i32) -> i32), + shim_sig!(extern "C" fn(i32, ...) -> i32), (link_name, abi, args), )?; From 536f0a32b7addcb4c164379f2038b0a5629ad815 Mon Sep 17 00:00:00 2001 From: zakrad <49591476+zakrad@users.noreply.github.com> Date: Mon, 24 Aug 2026 12:04:00 +0330 Subject: [PATCH 13/54] Add codegen test for static table search loop unrolling --- .../issues/static-table-search-loop-44041.rs | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 tests/codegen-llvm/issues/static-table-search-loop-44041.rs diff --git a/tests/codegen-llvm/issues/static-table-search-loop-44041.rs b/tests/codegen-llvm/issues/static-table-search-loop-44041.rs new file mode 100644 index 0000000000000..cbdfcd088aa11 --- /dev/null +++ b/tests/codegen-llvm/issues/static-table-search-loop-44041.rs @@ -0,0 +1,24 @@ +// Tests that a loop searching a small static array is unrolled and simplified +// down to a single comparison, with none of the unrolled branches left behind. +// See . + +//@ compile-flags: -Copt-level=3 + +#![crate_type = "lib"] + +static TABLE: [i32; 4] = [0; 4]; + +// CHECK-LABEL: @exists_in_table( +// CHECK-NOT: br {{.*}} +// CHECK: icmp eq i32 +// CHECK-NOT: br {{.*}} +// CHECK: ret i1 +#[no_mangle] +pub fn exists_in_table(v: i32) -> bool { + for &x in TABLE.iter() { + if x == v { + return true; + } + } + false +} From cfbb1d667d1b5c6ce068c35ec2fff3f9d7ecc692 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Wed, 12 Aug 2026 14:06:15 +0000 Subject: [PATCH 14/54] clippy::manual_is_ascii_check --- library/core/src/char/methods.rs | 2 ++ library/core/src/num/mod.rs | 1 + 2 files changed, 3 insertions(+) diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index f6930e0a60d42..f59219c09dc28 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -1,5 +1,7 @@ //! impl char {} +#![expect(clippy::manual_is_ascii_check, reason = "this module implements various is_ascii checks")] + use super::*; use crate::panic::const_panic; use crate::slice; diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 3fe7b95283446..59e470800dbd3 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -1,6 +1,7 @@ //! Numeric traits and functions for the built-in numeric types. #![stable(feature = "rust1", since = "1.0.0")] +#![expect(clippy::manual_is_ascii_check, reason = "this module implements various is_ascii checks")] use crate::convert::{BoundedCastFromInt, CheckedCastFromInt}; use crate::panic::const_panic; From e4f6415d71fb238afd51361ceec286f08390a599 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Wed, 12 Aug 2026 14:12:27 +0000 Subject: [PATCH 15/54] clippy::manual_ignore_case_cmp --- library/core/src/ascii/ascii_char.rs | 2 +- library/core/src/char/methods.rs | 1 + library/core/src/num/mod.rs | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/library/core/src/ascii/ascii_char.rs b/library/core/src/ascii/ascii_char.rs index de1adf9c9ec7c..801144826a2ed 100644 --- a/library/core/src/ascii/ascii_char.rs +++ b/library/core/src/ascii/ascii_char.rs @@ -635,7 +635,7 @@ impl AsciiChar { pub const fn eq_ignore_case(self, other: Self) -> bool { // FIXME(const-hack) `arg.to_u8().to_ascii_lowercase()` -> `arg.to_lowercase()` // once `PartialEq` is const for `Self`. - self.to_u8().to_ascii_lowercase() == other.to_u8().to_ascii_lowercase() + self.to_u8().eq_ignore_ascii_case(&other.to_u8()) } /// Converts this value to its upper case equivalent in-place. diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index f59219c09dc28..8009f6514945e 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -1987,6 +1987,7 @@ impl char { /// [to_ascii_lowercase]: #method.to_ascii_lowercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")] + #[expect(clippy::manual_ignore_case_cmp, reason = "implements eq_ignore_ascii_case")] #[inline] pub const fn eq_ignore_ascii_case(&self, other: &char) -> bool { self.to_ascii_lowercase() == other.to_ascii_lowercase() diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 59e470800dbd3..db41d23770477 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -732,6 +732,7 @@ impl u8 { /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")] + #[expect(clippy::manual_ignore_case_cmp, reason = "implements eq_ignore_ascii_case")] #[inline] pub const fn eq_ignore_ascii_case(&self, other: &u8) -> bool { self.to_ascii_lowercase() == other.to_ascii_lowercase() From 0f684e5dd9138654acff96d8cff9d2edcab93972 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Wed, 12 Aug 2026 15:25:02 +0000 Subject: [PATCH 16/54] clippy::manual_hash_one --- library/core/src/hash/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs index c7c8d57e1010d..f1a93a880e7f4 100644 --- a/library/core/src/hash/mod.rs +++ b/library/core/src/hash/mod.rs @@ -691,6 +691,7 @@ pub trait BuildHasher { /// ); /// ``` #[stable(feature = "build_hasher_simple_hash_one", since = "1.71.0")] + #[expect(clippy::manual_hash_one, reason = "implements hash_one")] fn hash_one(&self, x: T) -> u64 where Self: Sized, From cc299d706220ccf9499ebde99c3c923edb85d361 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Wed, 12 Aug 2026 15:53:51 +0000 Subject: [PATCH 17/54] clippy::excessive_precision --- library/core/src/num/f32.rs | 8 ++++---- library/core/src/num/f64.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 723e64aa9ac54..3f7b33770fc08 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -438,7 +438,7 @@ impl f32 { /// [`MANTISSA_DIGITS`]: f32::MANTISSA_DIGITS #[stable(feature = "assoc_int_consts", since = "1.43.0")] #[rustc_diagnostic_item = "f32_epsilon"] - pub const EPSILON: f32 = 1.19209290e-07_f32; + pub const EPSILON: f32 = 1.1920929e-07_f32; /// Smallest finite `f32` value. /// @@ -446,14 +446,14 @@ impl f32 { /// /// [`MAX`]: f32::MAX #[stable(feature = "assoc_int_consts", since = "1.43.0")] - pub const MIN: f32 = -3.40282347e+38_f32; + pub const MIN: f32 = -3.4028235e+38_f32; /// Smallest positive normal `f32` value. /// /// Equal to 2[`MIN_EXP`] − 1. /// /// [`MIN_EXP`]: f32::MIN_EXP #[stable(feature = "assoc_int_consts", since = "1.43.0")] - pub const MIN_POSITIVE: f32 = 1.17549435e-38_f32; + pub const MIN_POSITIVE: f32 = 1.1754944e-38_f32; /// Largest finite `f32` value. /// /// Equal to @@ -462,7 +462,7 @@ impl f32 { /// [`MANTISSA_DIGITS`]: f32::MANTISSA_DIGITS /// [`MAX_EXP`]: f32::MAX_EXP #[stable(feature = "assoc_int_consts", since = "1.43.0")] - pub const MAX: f32 = 3.40282347e+38_f32; + pub const MAX: f32 = 3.4028235e+38_f32; /// One greater than the minimum possible *normal* power of 2 exponent /// for a significand bounded by 1 ≤ x < 2 (i.e. the IEEE definition). diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index d23b3e5616302..5bc2f8d0feb32 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -437,7 +437,7 @@ impl f64 { /// [`MANTISSA_DIGITS`]: f64::MANTISSA_DIGITS #[stable(feature = "assoc_int_consts", since = "1.43.0")] #[rustc_diagnostic_item = "f64_epsilon"] - pub const EPSILON: f64 = 2.2204460492503131e-16_f64; + pub const EPSILON: f64 = 2.220446049250313e-16_f64; /// Smallest finite `f64` value. /// From fc3b63de1a60e5e6bd517cdba193a4c79d1bd7a4 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Wed, 12 Aug 2026 16:06:42 +0000 Subject: [PATCH 18/54] clippy::partialeq_ne_impl --- library/alloc/src/lib.rs | 1 + library/core/src/lib.rs | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 09b752491673e..f7aa47cfb17ac 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -59,6 +59,7 @@ #![allow(unused_features)] #![allow(incomplete_features)] #![allow(unused_attributes)] +#![expect(clippy::partialeq_ne_impl, reason = "we need to implement ne for a lot of alloc types")] #![stable(feature = "alloc", since = "1.36.0")] #![doc( html_playground_url = "https://play.rust-lang.org/", diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index f026434acbbc1..2aacd5d99b19b 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -187,6 +187,10 @@ #![feature(x86_amx_intrinsics)] // tidy-alphabetical-end +// tidy-alphabetical-start +#![expect(clippy::partialeq_ne_impl, reason = "we need to implement ne for a lot of core types")] +// tidy-alphabetical-end + // allow using `core::` in intra-doc links #[allow(unused_extern_crates)] extern crate self as core; From 71411ff301e06b4352119b3e1569f4495be1157c Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 13 Aug 2026 00:36:30 +0000 Subject: [PATCH 19/54] clippy::manual_contains --- library/core/src/slice/cmp.rs | 2 ++ library/std/src/sys/path/windows_prefix.rs | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/library/core/src/slice/cmp.rs b/library/core/src/slice/cmp.rs index 70d2392dfb3c6..acb74c9916dfd 100644 --- a/library/core/src/slice/cmp.rs +++ b/library/core/src/slice/cmp.rs @@ -386,6 +386,7 @@ impl SliceContains for T where T: PartialEq, { + #[expect(clippy::manual_contains, reason = "implements slice_contains")] default fn slice_contains(&self, x: &[Self]) -> bool { x.iter().any(|y| *y == *self) } @@ -393,6 +394,7 @@ where impl SliceContains for T { #[inline] + #[expect(clippy::manual_contains, reason = "implements slice_contains")] default fn slice_contains(&self, x: &[Self]) -> bool { if size_of::() == 1 { // SAFETY: `BytewiseEq` guarantees that values have no padding or provenance and diff --git a/library/std/src/sys/path/windows_prefix.rs b/library/std/src/sys/path/windows_prefix.rs index b9dfe754485ab..2e80b345cec8f 100644 --- a/library/std/src/sys/path/windows_prefix.rs +++ b/library/std/src/sys/path/windows_prefix.rs @@ -68,7 +68,7 @@ pub fn parse_prefix(path: &OsStr) -> Option> { // \\ // It's a POSIX path. - if cfg!(target_os = "cygwin") && !path.as_encoded_bytes().iter().any(|&x| x == b'\\') { + if cfg!(target_os = "cygwin") && !path.as_encoded_bytes().contains(&b'\\') { return None; } @@ -76,7 +76,7 @@ pub fn parse_prefix(path: &OsStr) -> Option> { // separator. if let Some(parser) = parser.strip_prefix(r"?\") // Cygwin allows `/` in verbatim paths. - && (cfg!(target_os = "cygwin") || !parser.prefix_bytes().iter().any(|&x| x == b'/')) + && (cfg!(target_os = "cygwin") || !parser.prefix_bytes().contains(&b'/')) { // \\?\ if let Some(parser) = parser.strip_prefix(r"UNC\") { From 1110bbb92ce95e7608f4de0a18aff283ecde0693 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 13 Aug 2026 01:25:04 +0000 Subject: [PATCH 20/54] clippy::single_match --- library/core/src/intrinsics/mod.rs | 11 +++-------- library/std/src/sys/process/unix/unix.rs | 5 ++--- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 2316fc4318918..673454abaf04f 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2915,14 +2915,9 @@ pub const fn contract_check_ensures bool + Copy, Ret>( // Do nothing ret } else { - match cond { - crate::option::Option::Some(cond) => { - if !cond(&ret) { - // Emit no unwind panic in case this was a safety requirement. - crate::panicking::panic_nounwind("failed ensures check"); - } - }, - crate::option::Option::None => {}, + if let crate::option::Option::Some(cond) = cond && !cond(&ret) { + // Emit no unwind panic in case this was a safety requirement. + crate::panicking::panic_nounwind("failed ensures check"); } ret } diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs index 6103fa3576f37..ba1286e0e5a09 100644 --- a/library/std/src/sys/process/unix/unix.rs +++ b/library/std/src/sys/process/unix/unix.rs @@ -928,9 +928,8 @@ impl Command { msg.msg_controllen = size_of::() as _; msg.msg_control = (&raw mut cmsg) as *mut _; - match cvt_r(|| libc::recvmsg(sock.as_raw(), &mut msg, libc::MSG_CMSG_CLOEXEC)) { - Err(_) => return -1, - Ok(_) => {} + if cvt_r(|| libc::recvmsg(sock.as_raw(), &mut msg, libc::MSG_CMSG_CLOEXEC)).is_err() { + return -1; } let hdr = CMSG_FIRSTHDR((&raw mut msg) as *mut _); From 6b058b4872891f130b0fccaefd8e8d80336cc398 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 13 Aug 2026 01:17:56 +0000 Subject: [PATCH 21/54] clippy::match_as_ref --- library/core/src/option.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 5d86f851dbd1d..9aaa80db055a4 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -737,6 +737,7 @@ impl Option { /// println!("still can print text: {text:?}"); /// ``` #[inline] + #[expect(clippy::match_as_ref, reason = "implements as_ref")] #[rustc_const_stable(feature = "const_option_basics", since = "1.48.0")] #[stable(feature = "rust1", since = "1.0.0")] pub const fn as_ref(&self) -> Option<&T> { @@ -759,6 +760,7 @@ impl Option { /// assert_eq!(x, Some(42)); /// ``` #[inline] + #[expect(clippy::match_as_ref, reason = "implements as_mut")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const fn as_mut(&mut self) -> Option<&mut T> { From 4ff5c855c304949f039204dd807c8df677949ebe Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 13 Aug 2026 13:53:55 +0000 Subject: [PATCH 22/54] clippy::default_constructed_unit_structs --- library/alloc/src/collections/btree/set.rs | 4 ++-- library/core/src/field.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index d06daa7c6c1b7..fb98c30ae5e69 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -901,7 +901,7 @@ impl BTreeSet { where T: Ord, { - self.map.insert(value, SetValZST::default()).is_none() + self.map.insert(value, SetValZST).is_none() } /// Adds a value to the set, replacing the existing element, if any, that is @@ -1483,7 +1483,7 @@ impl FromIterator for BTreeSet { impl BTreeSet { fn from_sorted_iter>(iter: I, alloc: A) -> BTreeSet { - let iter = iter.map(|k| (k, SetValZST::default())); + let iter = iter.map(|k| (k, SetValZST)); let map = BTreeMap::bulk_build_from_sorted_iter(iter, alloc); BTreeSet { map } } diff --git a/library/core/src/field.rs b/library/core/src/field.rs index 915a4c07b9e23..5a8ae7759bc1e 100644 --- a/library/core/src/field.rs +++ b/library/core/src/field.rs @@ -78,7 +78,7 @@ impl Default for FieldRepresentingType { fn default() -> Self { - Self { _phantom: PhantomData::default() } + Self { _phantom: PhantomData } } } From fe7445a91454c9b35497bea2175965aae506bb27 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 13 Aug 2026 13:56:21 +0000 Subject: [PATCH 23/54] clippy::redundant_closure --- library/alloc/src/collections/vec_deque/mod.rs | 4 ++-- library/std/src/sys/fs/windows.rs | 2 +- library/std/src/sys/process/unix/unix.rs | 2 +- library/std/src/thread/spawnhook.rs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 9095fc0d4abf4..a24e4d72fe38e 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -3312,7 +3312,7 @@ impl VecDeque { F: FnMut(&'a T) -> Ordering, { let (front, back) = self.as_slices(); - let cmp_back = back.first().map(|elem| f(elem)); + let cmp_back = back.first().map(&mut f); if let Some(Ordering::Equal) = cmp_back { Ok(front.len()) @@ -3423,7 +3423,7 @@ impl VecDeque { { let (front, back) = self.as_slices(); - if let Some(true) = back.first().map(|v| pred(v)) { + if let Some(true) = back.first().map(&mut pred) { back.partition_point(pred) + front.len() } else { front.partition_point(pred) diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs index c10b266ccb726..4446a4c3e3c8f 100644 --- a/library/std/src/sys/fs/windows.rs +++ b/library/std/src/sys/fs/windows.rs @@ -1114,7 +1114,7 @@ impl FileAttr { } pub fn changed_u64(&self) -> Option { - self.change_time.as_ref().map(|c| to_u64(c)) + self.change_time.as_ref().map(to_u64) } pub fn volume_serial_number(&self) -> Option { diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs index ba1286e0e5a09..8729ab65b86db 100644 --- a/library/std/src/sys/process/unix/unix.rs +++ b/library/std/src/sys/process/unix/unix.rs @@ -1316,7 +1316,7 @@ mod linux_child_ext { self.handle .pidfd .take() - .map(|fd| >::from_inner(fd)) + .map(>::from_inner) .ok_or_else(|| self) } } diff --git a/library/std/src/thread/spawnhook.rs b/library/std/src/thread/spawnhook.rs index 92fb586d39dcf..1bf22e0b0ea52 100644 --- a/library/std/src/thread/spawnhook.rs +++ b/library/std/src/thread/spawnhook.rs @@ -21,7 +21,7 @@ struct SpawnHooks { impl Drop for SpawnHooks { fn drop(&mut self) { let mut next = self.first.take(); - while let Some(SpawnHook { hook, next: n }) = next.and_then(|n| Arc::into_inner(n)) { + while let Some(SpawnHook { hook, next: n }) = next.and_then(Arc::into_inner) { drop(hook); next = n; } From 4c99af2ccf80dacc06a5c7ca0ba725147ff9f7b7 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 13 Aug 2026 14:12:28 +0000 Subject: [PATCH 24/54] clippy::derivable_impls --- library/alloc/src/bstr.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/library/alloc/src/bstr.rs b/library/alloc/src/bstr.rs index 9aa3064da886f..f48b2d52e80c1 100644 --- a/library/alloc/src/bstr.rs +++ b/library/alloc/src/bstr.rs @@ -42,7 +42,7 @@ use crate::vec::Vec; /// showing invalid UTF-8 as hex escapes or the Unicode replacement character, respectively. #[unstable(feature = "bstr", issue = "134915")] #[repr(transparent)] -#[derive(Clone)] +#[derive(Clone, Default)] #[doc(alias = "BString")] pub struct ByteString(pub Vec); @@ -187,13 +187,6 @@ impl BorrowMut for ByteString { // `impl BorrowMut for Vec` omitted to avoid inference failures -#[unstable(feature = "bstr", issue = "134915")] -impl Default for ByteString { - fn default() -> Self { - ByteString(Vec::new()) - } -} - // Omitted due to inference failures // // #[unstable(feature = "bstr", issue = "134915")] From bf79c6f96168929b64d79ce8e8da5f5ac9c63680 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 13 Aug 2026 14:14:36 +0000 Subject: [PATCH 25/54] clippy::partialeq_to_none --- library/std/src/fs.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 1e46ddb99e010..d0aa6cacd351b 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -3590,7 +3590,7 @@ impl DirBuilder { fn create_dir_all(&self, path: &Path) -> io::Result<()> { // if path's parent is None, it is "/" path, which should // return Ok immediately - if path.is_empty() || path.parent() == None { + if path.is_empty() || path.parent().is_none() { return Ok(()); } @@ -3601,7 +3601,7 @@ impl DirBuilder { // for relative paths like "foo/bar", the parent of // "foo" will be "" which there's no need to invoke // a mkdir syscall on - if ancestor.is_empty() || ancestor.parent() == None { + if ancestor.is_empty() || ancestor.parent().is_none() { break; } From 3dc163b2021d10f9944425149f996c24f560e69d Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 13 Aug 2026 14:20:50 +0000 Subject: [PATCH 26/54] clippy::unnecessary_map_or --- library/core/src/option.rs | 2 +- library/std/src/collections/hash/map.rs | 2 +- library/std/src/sys/fs/windows.rs | 12 ++++++------ library/test/src/term/terminfo/mod.rs | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 9aaa80db055a4..f91e9ffcc4567 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -1934,7 +1934,7 @@ impl Option { where P: [const] FnOnce(&mut T) -> bool + [const] Destruct, { - if self.as_mut().map_or(false, predicate) { self.take() } else { None } + if self.as_mut().is_some_and(predicate) { self.take() } else { None } } /// Replaces the actual value in the option by the value given in parameter, diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index fef0b1b4df88e..2858680a20a49 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -1457,7 +1457,7 @@ where return false; } - self.iter().all(|(key, value)| other.get(key).map_or(false, |v| *value == *v)) + self.iter().all(|(key, value)| other.get(key).is_some_and(|v| *value == *v)) } } diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs index 4446a4c3e3c8f..c99524375113a 100644 --- a/library/std/src/sys/fs/windows.rs +++ b/library/std/src/sys/fs/windows.rs @@ -784,9 +784,9 @@ impl File { pub fn set_times(&self, times: FileTimes) -> io::Result<()> { let is_zero = |t: c::FILETIME| t.dwLowDateTime == 0 && t.dwHighDateTime == 0; - if times.accessed.map_or(false, is_zero) - || times.modified.map_or(false, is_zero) - || times.created.map_or(false, is_zero) + if times.accessed.is_some_and(is_zero) + || times.modified.is_some_and(is_zero) + || times.created.is_some_and(is_zero) { return Err(io::const_error!( io::ErrorKind::InvalidInput, @@ -794,9 +794,9 @@ impl File { )); } let is_max = |t: c::FILETIME| t.dwLowDateTime == u32::MAX && t.dwHighDateTime == u32::MAX; - if times.accessed.map_or(false, is_max) - || times.modified.map_or(false, is_max) - || times.created.map_or(false, is_max) + if times.accessed.is_some_and(is_max) + || times.modified.is_some_and(is_max) + || times.created.is_some_and(is_max) { return Err(io::const_error!( io::ErrorKind::InvalidInput, diff --git a/library/test/src/term/terminfo/mod.rs b/library/test/src/term/terminfo/mod.rs index 75fa594908d56..6f712231e9888 100644 --- a/library/test/src/term/terminfo/mod.rs +++ b/library/test/src/term/terminfo/mod.rs @@ -67,7 +67,7 @@ impl TermInfo { Err(..) => return Err(Error::TermUnset), }; - if term.is_err() && env::var("MSYSCON").map_or(false, |s| "mintty.exe" == s) { + if term.is_err() && env::var("MSYSCON").is_ok_and(|s| "mintty.exe" == s) { // msys terminal Ok(msys_terminfo()) } else { From 3b4a6dd35856391cba901eae4f25ad685e9c262a Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 13 Aug 2026 14:23:54 +0000 Subject: [PATCH 27/54] clippy::manual_clear --- library/alloc/src/collections/vec_deque/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index a24e4d72fe38e..b007e3054ee6a 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -2049,6 +2049,7 @@ impl VecDeque { /// assert!(deque.is_empty()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[expect(clippy::manual_clear, reason = "implements clear")] #[inline] pub fn clear(&mut self) { self.truncate(0); From 9ea8c6e863866c2ace1f8534aa861a2ea75cf17b Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 13 Aug 2026 14:29:55 +0000 Subject: [PATCH 28/54] clippy::bind_instead_of_map --- library/core/src/slice/iter.rs | 8 ++++---- library/std/src/path.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index a054c9d742c88..1c721f2925eb5 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -1892,9 +1892,9 @@ impl<'a, T> Iterator for ChunksExact<'a, T> { #[inline] fn next(&mut self) -> Option<&'a [T]> { - self.v.split_at_checked(self.chunk_size).and_then(|(chunk, rest)| { + self.v.split_at_checked(self.chunk_size).map(|(chunk, rest)| { self.v = rest; - Some(chunk) + chunk }) } @@ -2048,9 +2048,9 @@ impl<'a, T> Iterator for ChunksExactMut<'a, T> { #[inline] fn next(&mut self) -> Option<&'a mut [T]> { // SAFETY: we have `&mut self`, so are allowed to temporarily materialize a mut slice - unsafe { &mut *self.v }.split_at_mut_checked(self.chunk_size).and_then(|(chunk, rest)| { + unsafe { &mut *self.v }.split_at_mut_checked(self.chunk_size).map(|(chunk, rest)| { self.v = rest; - Some(chunk) + chunk }) } diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 3052587389a91..dbfc00b2c2b47 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -2933,7 +2933,7 @@ impl Path { #[stable(feature = "path_file_prefix", since = "1.91.0")] #[must_use] pub fn file_prefix(&self) -> Option<&OsStr> { - self.file_name().map(split_file_at_dot).and_then(|(before, _after)| Some(before)) + self.file_name().map(split_file_at_dot).map(|(before, _after)| before) } /// Extracts the extension (without the leading dot) of [`self.file_name`], if possible. From 4f88014e819dfb22847bac86dfcf5e047d1b00b8 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 13 Aug 2026 14:57:26 +0000 Subject: [PATCH 29/54] clippy::redundant_slicing --- library/alloc/src/io/buffered/bufreader.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/io/buffered/bufreader.rs b/library/alloc/src/io/buffered/bufreader.rs index e8b3302e29b98..e8be1abc56e17 100644 --- a/library/alloc/src/io/buffered/bufreader.rs +++ b/library/alloc/src/io/buffered/bufreader.rs @@ -153,7 +153,7 @@ impl BufReader { let new = self.buf.read_more(&mut self.inner)?; if new == 0 { // end of file, no more bytes to read - return Ok(&self.buf.buffer()[..]); + return Ok(self.buf.buffer()); } debug_assert_eq!(self.buf.pos(), 0); } From 27eccc9019b58469fa10c36069ca2ded02174e6c Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 13 Aug 2026 15:03:21 +0000 Subject: [PATCH 30/54] clippy::transmutes_expressible_as_ptr_casts --- library/core/src/ptr/const_ptr.rs | 1 + library/core/src/ptr/mut_ptr.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 5601621f1408e..06e7bbb91bbab 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -149,6 +149,7 @@ impl *const T { #[doc = include_str!("./docs/addr.md")] #[must_use] #[inline(always)] + #[expect(clippy::transmutes_expressible_as_ptr_casts, reason = "implements pointer cast")] #[stable(feature = "strict_provenance", since = "1.84.0")] pub fn addr(self) -> usize { // A pointer-to-integer transmute currently has exactly the right semantics: it returns the diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 76eca86612a82..31e14fce4429a 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -140,6 +140,7 @@ impl *mut T { /// [without_provenance]: without_provenance_mut #[must_use] #[inline(always)] + #[expect(clippy::transmutes_expressible_as_ptr_casts, reason = "implements pointer cast")] #[stable(feature = "strict_provenance", since = "1.84.0")] pub fn addr(self) -> usize { // A pointer-to-integer transmute currently has exactly the right semantics: it returns the From b49b508a8b4afd07f59bea7f90e92f982cde620f Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 13 Aug 2026 15:10:50 +0000 Subject: [PATCH 31/54] clippy::manual_repeat_n --- library/std/src/sys/args/windows.rs | 4 ++-- library/test/src/term/terminfo/parm.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library/std/src/sys/args/windows.rs b/library/std/src/sys/args/windows.rs index bd26db7fea553..3a86f80a76f0c 100644 --- a/library/std/src/sys/args/windows.rs +++ b/library/std/src/sys/args/windows.rs @@ -115,7 +115,7 @@ fn parse_lp_cmd_line<'a, F: Fn() -> OsString>( BACKSLASH => { let backslash_count = code_units.advance_while(|w| w == BACKSLASH) + 1; if code_units.peek() == Some(QUOTE) { - cur.extend(iter::repeat(BACKSLASH.get()).take(backslash_count / 2)); + cur.extend(iter::repeat_n(BACKSLASH.get(), backslash_count / 2)); // The quote is escaped if there are an odd number of backslashes. if backslash_count % 2 == 1 { code_units.next(); @@ -123,7 +123,7 @@ fn parse_lp_cmd_line<'a, F: Fn() -> OsString>( } } else { // If there is no quote on the end then there is no escaping. - cur.extend(iter::repeat(BACKSLASH.get()).take(backslash_count)); + cur.extend(iter::repeat_n(BACKSLASH.get(), backslash_count)); } } // If `in_quotes` and not backslash escaped (see above) then a quote either diff --git a/library/test/src/term/terminfo/parm.rs b/library/test/src/term/terminfo/parm.rs index 529ec0c36e4a5..7426c1e009f55 100644 --- a/library/test/src/term/terminfo/parm.rs +++ b/library/test/src/term/terminfo/parm.rs @@ -1,6 +1,6 @@ //! Parameterized string expansion -use std::iter::repeat; +use std::iter::repeat_n; use self::Param::*; use self::States::*; @@ -520,10 +520,10 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result, String> { if flags.width > s.len() { let n = flags.width - s.len(); if flags.left { - s.extend(repeat(b' ').take(n)); + s.extend(repeat_n(b' ', n)); } else { let mut s_ = Vec::with_capacity(flags.width); - s_.extend(repeat(b' ').take(n)); + s_.extend(repeat_n(b' ', n)); s_.extend(s); s = s_; } From 6cb5350ca849a162520a294f643615228f2e712f Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 18 Aug 2026 20:42:03 +0000 Subject: [PATCH 32/54] clippy::to_digit_is_some --- library/core/src/char/methods.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index 8009f6514945e..ad0ae512f0f72 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -345,6 +345,7 @@ impl char { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_char_classify", since = "1.87.0")] + #[expect(clippy::to_digit_is_some, reason = "implements is_digit")] #[inline] pub const fn is_digit(self, radix: u32) -> bool { self.to_digit(radix).is_some() From d5d51bbeee8fbb58fc8c15131b07298dc464c311 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 18 Aug 2026 20:49:51 +0000 Subject: [PATCH 33/54] clippy::double_must_use --- library/alloc/src/boxed.rs | 3 --- library/alloc/src/rc.rs | 1 - library/alloc/src/sync.rs | 1 - library/alloc/src/vec/mod.rs | 1 - library/core/src/io/error.rs | 1 - library/std/src/panicking.rs | 1 - 6 files changed, 8 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 019749c77ae66..8ef478a6aab7b 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -813,7 +813,6 @@ impl Box { /// ``` #[unstable(feature = "clone_from_ref", issue = "149075")] //#[unstable(feature = "allocator_api", issue = "32838")] - #[must_use] #[inline] pub fn try_clone_from_ref(src: &T) -> Result, AllocError> { Box::try_clone_from_ref_in(src, Global) @@ -865,7 +864,6 @@ impl Box { /// ``` #[unstable(feature = "clone_from_ref", issue = "149075")] //#[unstable(feature = "allocator_api", issue = "32838")] - #[must_use] #[inline] pub fn try_clone_from_ref_in(src: &T, alloc: A) -> Result, AllocError> { struct DeallocDropGuard<'a, A: Allocator>(Layout, &'a A, NonNull); @@ -1161,7 +1159,6 @@ impl Box<[T], A> { /// ``` #[unstable(feature = "alloc_slice_into_array", issue = "148082")] #[inline] - #[must_use] pub fn into_array(self) -> Result, Self> { if self.len() == N { let (ptr, alloc) = Self::into_raw_with_allocator(self); diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index e4a803f28e121..01de5841ba0bb 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1257,7 +1257,6 @@ impl Rc<[T], A> { /// ``` #[unstable(feature = "alloc_slice_into_array", issue = "148082")] #[inline] - #[must_use] pub fn into_array(self) -> Result, Self> { if self.len() == N { let (ptr, alloc) = Self::into_raw_with_allocator(self); diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 625a29dd9b7a0..f73792016e3d3 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1416,7 +1416,6 @@ impl Arc<[T], A> { /// ``` #[unstable(feature = "alloc_slice_into_array", issue = "148082")] #[inline] - #[must_use] pub fn into_array(self) -> Result, Self> { if self.len() == N { let (ptr, alloc) = Self::into_raw_with_allocator(self); diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 94b21334c120c..bd15ec798460f 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1749,7 +1749,6 @@ impl Vec { /// ``` #[cfg(not(no_global_oom_handling))] #[unstable(feature = "alloc_slice_into_array", issue = "148082")] - #[must_use] pub fn into_array(self) -> Result, Self> { if self.len() == N { // SAFETY: `Box::into_array` is guaranteed to return `Ok` if the diff --git a/library/core/src/io/error.rs b/library/core/src/io/error.rs index 8491a42537092..c0de8822b456b 100644 --- a/library/core/src/io/error.rs +++ b/library/core/src/io/error.rs @@ -234,7 +234,6 @@ impl Error { #[doc(hidden)] #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")] - #[must_use] #[inline] pub fn into_custom_owner(self) -> result::Result { if matches!(self.repr.data(), ErrorData::Custom(..)) { diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 356b7daa293f4..5a4684a973942 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -175,7 +175,6 @@ pub fn set_hook(hook: Box) + 'static + Sync + Send>) { /// /// panic!("Normal panic"); /// ``` -#[must_use] #[stable(feature = "panic_hooks", since = "1.10.0")] pub fn take_hook() -> Box) + 'static + Sync + Send> { if thread::panicking() { From fd522d7ecedcde82116f55493d67c4b00292ea46 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 18 Aug 2026 21:02:04 +0000 Subject: [PATCH 34/54] clippy::seek_from_current --- library/core/src/io/seek.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/io/seek.rs b/library/core/src/io/seek.rs index 4c242c761dfe6..d24bf5ffb4024 100644 --- a/library/core/src/io/seek.rs +++ b/library/core/src/io/seek.rs @@ -142,6 +142,7 @@ pub trait Seek { /// } /// ``` #[stable(feature = "seek_convenience", since = "1.51.0")] + #[expect(clippy::seek_from_current, reason = "implements stream_position")] fn stream_position(&mut self) -> Result { self.seek(SeekFrom::Current(0)) } From ba77379e36c21f21fdaa5c21baf5fa773c705e2e Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 18 Aug 2026 21:07:26 +0000 Subject: [PATCH 35/54] clippy::mem_replace_option_with_some --- library/core/src/option.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index f91e9ffcc4567..14b60fd6d8a64 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -1825,7 +1825,7 @@ impl Option { // It could also be expressed as `unsafe { core::ptr::write(self, Some(f())) }`, but // no reason is currently known to use additional unsafe code here. - mem::forget(mem::replace(self, Some(f()))); + mem::forget(self.replace(f())); } // SAFETY: a `None` variant for `self` would have been replaced by a `Some` @@ -1957,6 +1957,7 @@ impl Option { #[inline] #[stable(feature = "option_replace", since = "1.31.0")] #[rustc_const_stable(feature = "const_option", since = "1.83.0")] + #[expect(clippy::mem_replace_option_with_some, reason = "implements Option::replace")] pub const fn replace(&mut self, value: T) -> Option { mem::replace(self, Some(value)) } From 17cac5aa4866afdfa4855b6877ed746ab95f9f2b Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 18 Aug 2026 21:12:42 +0000 Subject: [PATCH 36/54] clippy::mem_replace_option_with_none --- library/alloc/src/collections/btree/map.rs | 2 +- library/core/src/option.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index d8421d3c3f70a..b204732a673e3 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -670,7 +670,7 @@ impl BTreeMap { pub fn clear(&mut self) { // avoid moving the allocator drop(BTreeMap { - root: mem::replace(&mut self.root, None), + root: self.root.take(), length: mem::replace(&mut self.length, 0), alloc: self.alloc.clone(), _marker: PhantomData, diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 14b60fd6d8a64..f707c838a1175 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -1898,6 +1898,7 @@ impl Option { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_option", since = "1.83.0")] + #[expect(clippy::mem_replace_option_with_none, reason = "implements Option::take")] pub const fn take(&mut self) -> Option { // FIXME(const-hack) replace `mem::replace` by `mem::take` when the latter is const ready mem::replace(self, None) From 0bce2cce49b3af87bc177c9512d8880899f11ea8 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 18 Aug 2026 21:18:21 +0000 Subject: [PATCH 37/54] clippy::map_clone --- library/core/src/option.rs | 3 ++- library/core/src/result.rs | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index f707c838a1175..201019037148d 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -2158,6 +2158,7 @@ impl Option<&T> { /// ``` #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "rust1", since = "1.0.0")] + #[expect(clippy::map_clone, reason = "implements Option::cloned")] pub fn cloned(self) -> Option where T: Clone, @@ -2210,7 +2211,7 @@ impl Option<&mut T> { where T: Clone, { - self.as_deref().map(T::clone) + self.as_deref().cloned() } } diff --git a/library/core/src/result.rs b/library/core/src/result.rs index b257cd8c82a0e..d8c5fa48742bc 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -1738,6 +1738,7 @@ impl Result<&T, E> { /// ``` #[inline] #[stable(feature = "result_cloned", since = "1.59.0")] + #[expect(clippy::map_clone, reason = "implements Result::cloned")] pub fn cloned(self) -> Result where T: Clone, From db388688bfb2b65624fcc1653d5ffd5a1f8e2bca Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 18 Aug 2026 21:23:42 +0000 Subject: [PATCH 38/54] clippy::declare_interior_mutable_const --- library/core/src/sync/atomic.rs | 3 +++ library/std/src/sync/once.rs | 1 + 2 files changed, 4 insertions(+) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index e676a3851112d..12208b95307ee 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -534,6 +534,7 @@ pub enum Ordering { note = "the `new` function is now preferred", suggestion = "AtomicBool::new(false)" )] +#[expect(clippy::declare_interior_mutable_const, reason = "legacy atomic initializer")] pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false); #[cfg(target_has_atomic_load_store = "8")] @@ -3939,6 +3940,7 @@ macro_rules! atomic_int_ptr_sized { note = "the `new` function is now preferred", suggestion = "AtomicIsize::new(0)", )] + #[expect(clippy::declare_interior_mutable_const, reason = "legacy atomic initializer")] pub const ATOMIC_ISIZE_INIT: AtomicIsize = AtomicIsize::new(0); /// An [`AtomicUsize`] initialized to `0`. @@ -3949,6 +3951,7 @@ macro_rules! atomic_int_ptr_sized { note = "the `new` function is now preferred", suggestion = "AtomicUsize::new(0)", )] + #[expect(clippy::declare_interior_mutable_const, reason = "legacy atomic initializer")] pub const ATOMIC_USIZE_INIT: AtomicUsize = AtomicUsize::new(0); )* }; } diff --git a/library/std/src/sync/once.rs b/library/std/src/sync/once.rs index 62cac6afee751..9b555c32df99d 100644 --- a/library/std/src/sync/once.rs +++ b/library/std/src/sync/once.rs @@ -72,6 +72,7 @@ pub(crate) enum OnceExclusiveState { note = "the `Once::new()` function is now preferred", suggestion = "Once::new()" )] +#[expect(clippy::declare_interior_mutable_const, reason = "legacy Once initializer")] pub const ONCE_INIT: Once = Once::new(); impl Once { From ec3e1eaac79b8371ffe32540e19907a41f401784 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 18 Aug 2026 21:27:30 +0000 Subject: [PATCH 39/54] clippy::assign_op_pattern --- library/alloc/src/collections/linked_list.rs | 2 +- library/core/src/slice/sort/select.rs | 2 +- library/core/src/time.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index 8939b2f12f49c..a0542d2b5737c 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -369,7 +369,7 @@ impl LinkedList { // Fix the head ptr of the second part self.head = Some(split_node); - self.len = self.len - at; + self.len -= at; first_part } else { diff --git a/library/core/src/slice/sort/select.rs b/library/core/src/slice/sort/select.rs index fc31013caf88c..30058f516867e 100644 --- a/library/core/src/slice/sort/select.rs +++ b/library/core/src/slice/sort/select.rs @@ -116,7 +116,7 @@ fn partition_at_index_loop<'a, T, F>( } v = &mut v[mid..]; - index = index - mid; + index -= mid; ancestor_pivot = None; continue; } diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 682a61a07d10f..816da7a2fb7f2 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -1361,7 +1361,7 @@ macro_rules! sum_durations { total_secs = total_secs .checked_add(total_nanos / NANOS_PER_SEC as u64) .expect("overflow in iter::sum over durations"); - total_nanos = total_nanos % NANOS_PER_SEC as u64; + total_nanos %= NANOS_PER_SEC as u64; Duration::new(total_secs, total_nanos as u32) }}; } From 3bd3106b0ffcaad43b8f0968292e23ac1043f95b Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 18 Aug 2026 21:36:39 +0000 Subject: [PATCH 40/54] clippy::chunks_exact_to_as_chunks --- library/core/src/slice/ascii.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 2b6037b2ee53e..07920a36e6eda 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -666,10 +666,9 @@ const fn is_ascii(bytes: &[u8]) -> bool { } else { // For small inputs, use usize-at-a-time processing to avoid SSE2 call overhead. if bytes.len() < SIMD_MIN_LEN { - let chunks = bytes.chunks_exact(USIZE_SIZE); - let remainder = chunks.remainder(); + let (chunks, remainder) = bytes.as_chunks::(); for chunk in chunks { - let word = usize::from_ne_bytes(chunk.try_into().unwrap()); + let word = usize::from_ne_bytes(*chunk); if (word & NONASCII_MASK) != 0 { return false; } From 167a56a5dc8018d16c09e16a5a33541f1ea103fa Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Wed, 19 Aug 2026 01:26:27 +0000 Subject: [PATCH 41/54] clippy::needless_raw_string_hashes --- library/core/src/panicking.rs | 8 ++++---- library/std/src/sys/args/windows.rs | 2 +- library/test/src/formatters/json.rs | 2 +- library/test/src/test_result.rs | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 46790b620127b..04722e4e2fc10 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -445,14 +445,14 @@ fn assert_failed_inner( match args { Some(args) => panic!( - r#"assertion `left {op} right` failed: {args} + r"assertion `left {op} right` failed: {args} left: {left:?} - right: {right:?}"# + right: {right:?}" ), None => panic!( - r#"assertion `left {op} right` failed + r"assertion `left {op} right` failed left: {left:?} - right: {right:?}"# + right: {right:?}" ), } } diff --git a/library/std/src/sys/args/windows.rs b/library/std/src/sys/args/windows.rs index 3a86f80a76f0c..4a450a72cdccd 100644 --- a/library/std/src/sys/args/windows.rs +++ b/library/std/src/sys/args/windows.rs @@ -295,7 +295,7 @@ pub(crate) fn make_bat_command_line( force_quotes: bool, ) -> io::Result> { const INVALID_ARGUMENT_ERROR: io::Error = - io::const_error!(io::ErrorKind::InvalidInput, r#"batch file arguments are invalid"#); + io::const_error!(io::ErrorKind::InvalidInput, r"batch file arguments are invalid"); // Set the start of the command line to `cmd.exe /c "` // It is necessary to surround the command in an extra pair of quotes, // hence the trailing quote here. It will be closed after all arguments diff --git a/library/test/src/formatters/json.rs b/library/test/src/formatters/json.rs index 4a101f00d74b6..df62d0fd7f435 100644 --- a/library/test/src/formatters/json.rs +++ b/library/test/src/formatters/json.rs @@ -48,7 +48,7 @@ impl JsonFormatter { String::from("") }; let extra_json = - if let Some(extra) = extra { format!(r#", {extra}"#) } else { String::from("") }; + if let Some(extra) = extra { format!(r", {extra}") } else { String::from("") }; let newline = "\n"; self.writeln_message(&format!( diff --git a/library/test/src/test_result.rs b/library/test/src/test_result.rs index 4cb43fc45fd6c..b2457e031fd19 100644 --- a/library/test/src/test_result.rs +++ b/library/test/src/test_result.rs @@ -60,15 +60,15 @@ pub(crate) fn calc_result( TestResult::TrOk } else if let Some(panic_str) = maybe_panic_str { TestResult::TrFailedMsg(format!( - r#"panic did not contain expected string + r"panic did not contain expected string panic message: {panic_str:?} - expected substring: {msg:?}"# + expected substring: {msg:?}" )) } else { TestResult::TrFailedMsg(format!( - r#"expected panic with string value, + r"expected panic with string value, found non-string value: `{:?}` - expected substring: {msg:?}"#, + expected substring: {msg:?}", (*err).type_id() )) } From 503192cfbda7ce8a610f34d04e1da723a2f062b2 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Wed, 19 Aug 2026 14:30:12 +0000 Subject: [PATCH 42/54] clippy::approx_constant --- library/core/src/num/f128.rs | 1 + library/core/src/num/f16.rs | 1 + library/core/src/num/f32.rs | 1 + library/core/src/num/f64.rs | 1 + 4 files changed, 4 insertions(+) diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 45b4b80e9e268..994233186a193 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -10,6 +10,7 @@ //! defined directly on the `f128` type. #![unstable(feature = "f128", issue = "116909")] +#![expect(clippy::approx_constant, reason = "this module defines f128 constants")] use crate::convert::{FloatToFloat, FloatToInt}; use crate::num::FpCategory; diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index e8f2e37f93c67..c1a64fd7fb602 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -10,6 +10,7 @@ //! defined directly on the `f16` type. #![unstable(feature = "f16", issue = "116909")] +#![expect(clippy::approx_constant, reason = "this module defines f16 constants")] use crate::convert::{FloatToFloat, FloatToInt}; use crate::num::FpCategory; diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 3f7b33770fc08..eb1da9c7c7c6e 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -10,6 +10,7 @@ //! defined directly on the `f32` type. #![stable(feature = "rust1", since = "1.0.0")] +#![expect(clippy::approx_constant, reason = "this module defines f32 constants")] use crate::convert::{FloatToFloat, FloatToInt}; use crate::num::FpCategory; diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 5bc2f8d0feb32..0a3baf039e639 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -10,6 +10,7 @@ //! defined directly on the `f64` type. #![stable(feature = "rust1", since = "1.0.0")] +#![expect(clippy::approx_constant, reason = "this module defines f64 constants")] use crate::convert::{FloatToFloat, FloatToInt}; use crate::num::FpCategory; From 85e21525fb48a28d74d412c9023d99ce53153c38 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Wed, 12 Aug 2026 15:42:04 +0000 Subject: [PATCH 43/54] clippy::neg_cmp_op_on_partial_ord --- library/core/src/num/f128.rs | 4 +++- library/core/src/num/f16.rs | 4 +++- library/core/src/num/f32.rs | 4 +++- library/core/src/num/f64.rs | 4 +++- library/core/src/ops/range.rs | 2 ++ library/core/src/range.rs | 2 ++ 6 files changed, 16 insertions(+), 4 deletions(-) diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 994233186a193..d52e817c9e3db 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -1500,6 +1500,7 @@ impl f128 { #[inline] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] + #[expect(clippy::neg_cmp_op_on_partial_ord, reason = "NaN is also invalid")] pub const fn clamp(mut self, min: f128, max: f128) -> f128 { const_assert!( min <= max, @@ -1544,8 +1545,9 @@ impl f128 { #[inline] #[unstable(feature = "clamp_magnitude", issue = "148519")] #[must_use = "this returns the clamped value and does not modify the original"] + #[expect(clippy::neg_cmp_op_on_partial_ord, reason = "NaN is also invalid")] pub fn clamp_magnitude(self, limit: f128) -> f128 { - assert!(limit >= 0.0, "limit must be non-negative"); + assert!(limit >= 0.0, "limit must be non-negative and not NaN"); let limit = limit.abs(); // Canonicalises -0.0 to 0.0 self.clamp(-limit, limit) } diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index c1a64fd7fb602..186e83a9cd6b5 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -1486,6 +1486,7 @@ impl f16 { #[inline] #[unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] + #[expect(clippy::neg_cmp_op_on_partial_ord, reason = "NaN is also invalid")] pub const fn clamp(mut self, min: f16, max: f16) -> f16 { const_assert!( min <= max, @@ -1530,8 +1531,9 @@ impl f16 { #[inline] #[unstable(feature = "clamp_magnitude", issue = "148519")] #[must_use = "this returns the clamped value and does not modify the original"] + #[expect(clippy::neg_cmp_op_on_partial_ord, reason = "NaN is also invalid")] pub fn clamp_magnitude(self, limit: f16) -> f16 { - assert!(limit >= 0.0, "limit must be non-negative"); + assert!(limit >= 0.0, "limit must be non-negative and not NaN"); let limit = limit.abs(); // Canonicalises -0.0 to 0.0 self.clamp(-limit, limit) } diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index eb1da9c7c7c6e..3c6b58a2b4b25 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1660,6 +1660,7 @@ impl f32 { #[stable(feature = "clamp", since = "1.50.0")] #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] + #[expect(clippy::neg_cmp_op_on_partial_ord, reason = "Nan is also invalid")] pub const fn clamp(mut self, min: f32, max: f32) -> f32 { const_assert!( min <= max, @@ -1701,8 +1702,9 @@ impl f32 { #[must_use = "this returns the clamped value and does not modify the original"] #[unstable(feature = "clamp_magnitude", issue = "148519")] #[inline] + #[expect(clippy::neg_cmp_op_on_partial_ord, reason = "NaN is also invalid")] pub fn clamp_magnitude(self, limit: f32) -> f32 { - assert!(limit >= 0.0, "limit must be non-negative"); + assert!(limit >= 0.0, "limit must be non-negative and not NaN"); let limit = limit.abs(); // Canonicalises -0.0 to 0.0 self.clamp(-limit, limit) } diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 0a3baf039e639..8c433a5cf941d 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1638,6 +1638,7 @@ impl f64 { #[stable(feature = "clamp", since = "1.50.0")] #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] + #[expect(clippy::neg_cmp_op_on_partial_ord, reason = "NaN is also invalid")] pub const fn clamp(mut self, min: f64, max: f64) -> f64 { const_assert!( min <= max, @@ -1679,8 +1680,9 @@ impl f64 { #[must_use = "this returns the clamped value and does not modify the original"] #[unstable(feature = "clamp_magnitude", issue = "148519")] #[inline] + #[expect(clippy::neg_cmp_op_on_partial_ord, reason = "NaN is also invalid")] pub fn clamp_magnitude(self, limit: f64) -> f64 { - assert!(limit >= 0.0, "limit must be non-negative"); + assert!(limit >= 0.0, "limit must be non-negative and not NaN"); let limit = limit.abs(); // Canonicalises -0.0 to 0.0 self.clamp(-limit, limit) } diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs index ebb6c3ddb938c..19830365faa32 100644 --- a/library/core/src/ops/range.rs +++ b/library/core/src/ops/range.rs @@ -148,6 +148,7 @@ impl> Range { #[inline] #[stable(feature = "range_is_empty", since = "1.47.0")] #[rustc_const_unstable(feature = "const_range", issue = "none")] + #[expect(clippy::neg_cmp_op_on_partial_ord, reason = "incomparable ranges are empty")] pub const fn is_empty(&self) -> bool where Idx: [const] PartialOrd, @@ -568,6 +569,7 @@ impl> RangeInclusive { #[stable(feature = "range_is_empty", since = "1.47.0")] #[inline] #[rustc_const_unstable(feature = "const_range", issue = "none")] + #[expect(clippy::neg_cmp_op_on_partial_ord, reason = "incomparable ranges are empty")] pub const fn is_empty(&self) -> bool where Idx: [const] PartialOrd, diff --git a/library/core/src/range.rs b/library/core/src/range.rs index 557587b4e9a88..81f4b2ce78c9c 100644 --- a/library/core/src/range.rs +++ b/library/core/src/range.rs @@ -162,6 +162,7 @@ impl> Range { #[inline] #[stable(feature = "new_range_api", since = "1.96.0")] #[rustc_const_unstable(feature = "const_range", issue = "none")] + #[expect(clippy::neg_cmp_op_on_partial_ord, reason = "incomparable ranges are empty")] pub const fn is_empty(&self) -> bool where Idx: [const] PartialOrd, @@ -320,6 +321,7 @@ impl> RangeInclusive { #[stable(feature = "new_range_inclusive_api", since = "1.95.0")] #[inline] #[rustc_const_unstable(feature = "const_range", issue = "none")] + #[expect(clippy::neg_cmp_op_on_partial_ord, reason = "incomparable ranges are empty")] pub const fn is_empty(&self) -> bool where Idx: [const] PartialOrd, From 1cb99178f963abff8865e02771bef948c795ddf3 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 18 Aug 2026 21:42:25 +0000 Subject: [PATCH 44/54] Ignore clippy failures in stdarch submodule --- library/core/src/lib.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 2aacd5d99b19b..ab47e7235bcc6 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -364,7 +364,9 @@ pub mod primitive; unsafe_op_in_unsafe_fn, ambiguous_glob_reexports, deprecated_in_future, - unreachable_pub + unreachable_pub, + // FIXME: stdach is a submodule so clippy lints should be fixed (and ideally enforced) there + clippy::all, )] #[allow(rustdoc::bare_urls)] mod core_arch; From 3df0d082f1b47989aa793338b9869ec37e71cbf5 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 18 Aug 2026 22:59:35 +0000 Subject: [PATCH 45/54] Enforce even more clippy lints in CI --- src/bootstrap/src/core/build_steps/clippy.rs | 51 +++++++++++++++----- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs index dc3e3efb80ee5..9b8377f23ccd5 100644 --- a/src/bootstrap/src/core/build_steps/clippy.rs +++ b/src/bootstrap/src/core/build_steps/clippy.rs @@ -38,7 +38,6 @@ const IGNORED_RULES_FOR_STD_AND_RUSTC: &[&str] = &[ "too_many_arguments", "needless_lifetimes", // people want to keep the lifetimes "wrong_self_convention", - "approx_constant", // libcore is what defines those ]; fn lint_args(builder: &Builder<'_>, config: &LintConfig, ignored_rules: &[&str]) -> Vec { @@ -572,29 +571,57 @@ impl CommandLineStep for CI { allow: vec!["clippy::all".into()], warn: vec![], deny: vec![ + // the entire correctness group should always be enforced. "clippy::correctness".into(), + // tidy-alphabetic-start + "clippy::approx_constant".into(), + "clippy::assign_op_pattern".into(), + "clippy::bind_instead_of_map".into(), + "clippy::borrow_deref_ref".into(), "clippy::char_lit_as_u8".into(), + "clippy::chunks_exact_to_as_chunks".into(), + "clippy::declare_interior_mutable_const".into(), + "clippy::default_constructed_unit_structs".into(), + "clippy::derivable_impls".into(), + "clippy::double_must_use".into(), + "clippy::excessive_precision".into(), + "clippy::explicit_auto_deref".into(), + "clippy::filter_map_next".into(), "clippy::four_forward_slashes".into(), + "clippy::int_plus_one".into(), + "clippy::legacy_numeric_constants".into(), + "clippy::let_and_return".into(), + "clippy::manual_repeat_n".into(), + "clippy::map_clone".into(), + "clippy::match_as_ref".into(), + "clippy::mem_replace_option_with_none".into(), + "clippy::mem_replace_option_with_some".into(), + "clippy::needless_as_bytes".into(), "clippy::needless_bool".into(), "clippy::needless_bool_assign".into(), + "clippy::needless_borrow".into(), + "clippy::needless_raw_string_hashes".into(), + "clippy::needless_return".into(), + "clippy::neg_cmp_op_on_partial_ord".into(), "clippy::non_minimal_cfg".into(), + "clippy::op_ref".into(), + "clippy::partialeq_ne_impl".into(), + "clippy::partialeq_to_none".into(), "clippy::print_literal".into(), + "clippy::ptr_offset_with_cast".into(), + "clippy::redundant_closure".into(), + "clippy::redundant_pattern_matching".into(), + "clippy::redundant_slicing".into(), "clippy::same_item_push".into(), + "clippy::seek_from_current".into(), "clippy::single_char_add_str".into(), + "clippy::single_match".into(), + "clippy::to_digit_is_some".into(), "clippy::to_string_in_format_args".into(), "clippy::unconditional_recursion".into(), - "clippy::int_plus_one".into(), - "clippy::legacy_numeric_constants".into(), + "clippy::unnecessary_map_or".into(), "clippy::zero_divided_by_zero".into(), - "clippy::len_zero".into(), - "clippy::needless_as_bytes".into(), - "clippy::ptr_offset_with_cast".into(), - "clippy::let_and_return".into(), - "clippy::needless_return".into(), - "clippy::needless_borrow".into(), - "clippy::op_ref".into(), - "clippy::borrow_deref_ref".into(), - "clippy::explicit_auto_deref".into(), + // tidy-alphabetic-end ], forbid: vec![], }; From bc9565bc58b884dcd8370b98a346121a79fd8c79 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Wed, 19 Aug 2026 02:41:43 +0000 Subject: [PATCH 46/54] Allow lints on backtrace-rs --- library/std/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 980ec4416f04a..590c5e62557a0 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -739,7 +739,7 @@ mod panicking; #[path = "../../backtrace/src/lib.rs"] #[allow(dead_code, unused_attributes, implicit_provenance_casts, unsafe_op_in_unsafe_fn)] -#[allow(clippy::len_zero, clippy::needless_borrow)] // FIXME +#[allow(clippy::len_zero, clippy::needless_borrow, clippy::filter_map_next)] // FIXME mod backtrace_rs; #[stable(feature = "cfg_select", since = "1.95.0")] From d712c4ee33cdcb63131bee8b63e522ff58560a74 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Wed, 19 Aug 2026 11:53:24 +0000 Subject: [PATCH 47/54] ignore clippy::redundant_pattern_matching This can affect drop order --- src/bootstrap/src/core/build_steps/clippy.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs index 9b8377f23ccd5..99648425a8987 100644 --- a/src/bootstrap/src/core/build_steps/clippy.rs +++ b/src/bootstrap/src/core/build_steps/clippy.rs @@ -38,6 +38,7 @@ const IGNORED_RULES_FOR_STD_AND_RUSTC: &[&str] = &[ "too_many_arguments", "needless_lifetimes", // people want to keep the lifetimes "wrong_self_convention", + "redundant_pattern_matching", // can affect drop order ]; fn lint_args(builder: &Builder<'_>, config: &LintConfig, ignored_rules: &[&str]) -> Vec { @@ -610,7 +611,6 @@ impl CommandLineStep for CI { "clippy::print_literal".into(), "clippy::ptr_offset_with_cast".into(), "clippy::redundant_closure".into(), - "clippy::redundant_pattern_matching".into(), "clippy::redundant_slicing".into(), "clippy::same_item_push".into(), "clippy::seek_from_current".into(), From 2a8651f3f7576b250704b9b847921b1f2409edd1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 24 Aug 2026 13:44:07 +0200 Subject: [PATCH 48/54] partially revert 34e5379bef92f5b8d82cccd27cc926dd34d0402b --- src/tools/miri/README.md | 4 - src/tools/miri/src/bin/miri.rs | 12 -- src/tools/miri/src/borrow_tracker/mod.rs | 3 - .../src/borrow_tracker/stacked_borrows/mod.rs | 7 +- .../src/borrow_tracker/tree_borrows/mod.rs | 19 ++- .../both_borrows/box-custom-alloc-aliasing.rs | 131 ------------------ .../box-custom-alloc-aliasing.stack.stderr | 37 ----- .../box-custom-alloc-aliasing.tree.stderr | 52 ------- .../tests/pass/box-custom-alloc-aliasing.rs | 6 +- 9 files changed, 17 insertions(+), 254 deletions(-) delete mode 100644 src/tools/miri/tests/fail/both_borrows/box-custom-alloc-aliasing.rs delete mode 100644 src/tools/miri/tests/fail/both_borrows/box-custom-alloc-aliasing.stack.stderr delete mode 100644 src/tools/miri/tests/fail/both_borrows/box-custom-alloc-aliasing.tree.stderr diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index d674774184a22..2eb9ababffc8b 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -531,10 +531,6 @@ to Miri failing to detect cases of undefined behavior in a program. track interior mutable data on the level of references instead of on the byte-level as is done by default. Therefore, with this flag, Tree Borrows will be more permissive. -* `-Zmiri-tree-borrows-relax-custom-allocator-uniqueness` disables uniqueness assumptions for - `Box` where `A` is not `Global`. The exact aliasing rules for such custom allocators are - still up in the air, and by default Miri is conservative and rejects some allocator - implementations that incur relevant aliasing between the allocation and the allocator. * `-Zmiri-force-page-size=` overrides the default page size for an architecture, in multiples of 1k. `4` is default for most targets. This value should always be a power of 2 and nonzero. diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 7623422a66e57..19d1f5d6f461c 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -474,8 +474,6 @@ fn main() -> ExitCode { Some(BorrowTrackerMethod::TreeBorrows(TreeBorrowsParams { precise_interior_mut: true, implicit_writes: false, - // We default this to "unique" for now to keep the design space open. - box_custom_allocator_unique: true, })); } else if arg == "-Zmiri-tree-borrows-no-precise-interior-mut" { match &mut miri_config.borrow_tracker { @@ -497,16 +495,6 @@ fn main() -> ExitCode { "`-Zmiri-tree-borrows` is required before `-Zmiri-tree-borrows-implicit-writes`" ), }; - } else if arg == "-Zmiri-tree-borrows-relax-custom-allocator-uniqueness" { - match &mut miri_config.borrow_tracker { - Some(BorrowTrackerMethod::TreeBorrows(params)) => { - params.box_custom_allocator_unique = false; - } - _ => - fatal_error!( - "`-Zmiri-tree-borrows` is required before `-Zmiri-tree-borrows-relax-custom-allocator-uniqueness`" - ), - }; } else if arg == "-Zmiri-disable-data-race-detector" { miri_config.data_race_detector = false; miri_config.weak_memory_emulation = false; diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs index f11799e0736f9..65660956220ea 100644 --- a/src/tools/miri/src/borrow_tracker/mod.rs +++ b/src/tools/miri/src/borrow_tracker/mod.rs @@ -226,12 +226,9 @@ pub enum BorrowTrackerMethod { /// Parameters that Tree Borrows can take. #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct TreeBorrowsParams { - /// Controls whether we track `UnsafeCell` with byte precision. pub precise_interior_mut: bool, /// Controls whether `&mut` function arguments are immediately activated with an implicit write. pub implicit_writes: bool, - /// Controls whether `Box` with custom allocator is considered unique. - pub box_custom_allocator_unique: bool, } impl BorrowTrackerMethod { diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index 9ca3212edef2a..d6ac9390dc0eb 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -869,7 +869,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { RetagMode::None => return interp_ok(None), // no retagging }; let new_perm = if ty.is_box() { - NewPermission::from_box_ty(val.layout.ty, mode, this) + if ty.is_box_global(*this.tcx) { + NewPermission::from_box_ty(val.layout.ty, mode, this) + } else { + // Boxes with custom allocator are not retagged. + return interp_ok(None); + } } else { NewPermission::from_ref_ty(val.layout.ty, mode, this) }; diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs index 185596d7232e9..df349667a47c9 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs @@ -479,25 +479,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx, Option>> { let this = self.eval_context_mut(); let new_perm = match *ty.kind() { + _ if ty.is_box_global(*this.tcx) => { + // The `None` marks this as a Box. + NewPermission::new(ty.builtin_deref(true).unwrap(), None, mode, this) + } ty::Ref(_, pointee, mutability) => NewPermission::new(pointee, Some(mutability), mode, this), - _ if ty.is_box() => { - let box_custom_allocator_unique = - this.get_tree_borrows_params().box_custom_allocator_unique; - if box_custom_allocator_unique || ty.is_box_global(*this.tcx) { - // The `None` marks this as a Box. - NewPermission::new(ty.builtin_deref(true).unwrap(), None, mode, this) - } else { - // No retagging for boxes with custom allocators. - None - } - } ty::RawPtr(..) => { assert!(mode == RetagMode::Raw); // We don't give new tags to raw pointers. None } + _ if ty.is_box() => { + // No retagging for boxes with custom allocators. + None + } _ => panic!("tb_retag_ptr_value: invalid type {ty}"), }; if let Some(new_perm) = new_perm { diff --git a/src/tools/miri/tests/fail/both_borrows/box-custom-alloc-aliasing.rs b/src/tools/miri/tests/fail/both_borrows/box-custom-alloc-aliasing.rs deleted file mode 100644 index 93626a354d037..0000000000000 --- a/src/tools/miri/tests/fail/both_borrows/box-custom-alloc-aliasing.rs +++ /dev/null @@ -1,131 +0,0 @@ -//! Test related to : -//! `Box` with custom allocators are still `noalias`, leading to UB. - -//@revisions: stack tree -//@[tree]compile-flags: -Zmiri-tree-borrows -//@normalize-stderr-test: "\[0x[a-fx\d.]+\]" -> "[RANGE]" -#![feature(allocator_api)] - -use std::alloc::{AllocError, Allocator, Layout}; -use std::cell::{Cell, UnsafeCell}; -use std::mem; -use std::ptr::{self, NonNull, addr_of}; -use std::thread::{self, ThreadId}; - -const BIN_SIZE: usize = 8; - -// A bin represents a collection of blocks of a specific layout. -#[repr(align(128))] -struct MyBin { - top: Cell, - thread_id: ThreadId, - memory: UnsafeCell<[usize; BIN_SIZE]>, -} - -impl MyBin { - fn pop(&self) -> Option> { - let top = self.top.get(); - if top == BIN_SIZE { - return None; - } - // Cast the *entire* thing to a raw pointer to not restrict its provenance. - let bin = self as *const MyBin; - let base_ptr = UnsafeCell::raw_get(unsafe { addr_of!((*bin).memory) }).cast::(); - let ptr = unsafe { NonNull::new_unchecked(base_ptr.add(top)) }; - self.top.set(top + 1); - Some(ptr.cast()) - } - - // Pretends to not be a throwaway allocation method like this. A more realistic - // substitute is using intrusive linked lists, which requires access to the - // metadata of this bin as well. - unsafe fn push(&self, ptr: NonNull) { - // For now just check that this really is in this bin. - let start = self.memory.get().addr(); - let end = start + BIN_SIZE * mem::size_of::(); - let addr = ptr.addr().get(); - assert!((start..end).contains(&addr)); - - // We can't update `top` as this may not be the last bin, but we can pretend to do so - // such that the aliasing model checks things. - // We access this via raw pointers so that the error span is in this file. - let top_ptr = (&raw const self.top) as *mut usize; - let top = top_ptr.read(); - //~[tree]^ERROR: /read access .* is forbidden/ - top_ptr.write(top); - } -} - -// A collection of bins. -struct MyAllocator { - thread_id: ThreadId, - // Pretends to be some complex collection of bins, such as an array of linked lists. - bins: Box<[MyBin; 1]>, -} - -impl MyAllocator { - fn new() -> Self { - let thread_id = thread::current().id(); - MyAllocator { - thread_id, - bins: Box::new( - [MyBin { top: Cell::new(0), thread_id, memory: UnsafeCell::default() }; 1], - ), - } - } - - // Pretends to be expensive finding a suitable bin for the layout. - fn find_bin(&self, layout: Layout) -> Option<&MyBin> { - if layout == Layout::new::() { Some(&self.bins[0]) } else { None } - } -} - -unsafe impl Allocator for MyAllocator { - fn allocate(&self, layout: Layout) -> Result, AllocError> { - // Expensive bin search. - let bin = self.find_bin(layout).ok_or(AllocError)?; - let ptr = bin.pop().ok_or(AllocError)?; - Ok(NonNull::slice_from_raw_parts(ptr, layout.size())) - } - - unsafe fn deallocate(&self, ptr: NonNull, _layout: Layout) { - // Make sure accesses via `self` don't disturb anything. - let _val = self.bins[0].top.get(); - // Since manually finding the corresponding bin of `ptr` is very expensive, - // doing pointer arithmetics is preferred. - // But this means we access `top` via `ptr` rather than `self`! - // That is fundamentally the source of the aliasing trouble in this example. - let their_bin = ptr.as_ptr().map_addr(|addr| addr & !127).cast::(); - let thread_id = ptr::read(ptr::addr_of!((*their_bin).thread_id)); - //~[stack]^ERROR: tag does not exist in the borrow stack - if self.thread_id == thread_id { - unsafe { (*their_bin).push(ptr) }; - } else { - todo!("Deallocating from another thread"); - } - // Make sure we can also still access this via `self` after the rest is done. - let _val = self.bins[0].top.get(); - } -} - -// Make sure to involve `Box` in allocating these, -// as that's where `noalias` may come from. -fn v1(t: T, a: A) -> Vec { - (Box::new_in([t], a) as Box<[T], A>).into_vec() -} -fn v2(t: T, a: A) -> Vec { - let v = v1(t, a); - // There was a bug in `into_boxed_slice` that caused aliasing issues, - // so round-trip through that as well. - v.into_boxed_slice().into_vec() -} - -fn main() { - assert!(mem::size_of::() <= 128); // if it grows bigger, the trick to access the "header" no longer works - let my_alloc = MyAllocator::new(); - let a = v1(1usize, &my_alloc); - let b = v2(2usize, &my_alloc); - assert_eq!(a[0] + 1, b[0]); - assert_eq!(addr_of!(a[0]).wrapping_add(1), addr_of!(b[0])); - drop((a, b)); -} diff --git a/src/tools/miri/tests/fail/both_borrows/box-custom-alloc-aliasing.stack.stderr b/src/tools/miri/tests/fail/both_borrows/box-custom-alloc-aliasing.stack.stderr deleted file mode 100644 index 12fb11665fe6d..0000000000000 --- a/src/tools/miri/tests/fail/both_borrows/box-custom-alloc-aliasing.stack.stderr +++ /dev/null @@ -1,37 +0,0 @@ -error: Undefined Behavior: attempting a read access using at ALLOC[RANGE], but that tag does not exist in the borrow stack for this location - --> tests/fail/both_borrows/box-custom-alloc-aliasing.rs:LL:CC - | -LL | let thread_id = ptr::read(ptr::addr_of!((*their_bin).thread_id)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this error occurs as part of an access at ALLOC[RANGE] - | - = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental - = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information -help: was created by a Unique retag at offsets [RANGE] - --> tests/fail/both_borrows/box-custom-alloc-aliasing.rs:LL:CC - | -LL | (Box::new_in([t], a) as Box<[T], A>).into_vec() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: stack backtrace: - 0: ::deallocate - at tests/fail/both_borrows/box-custom-alloc-aliasing.rs:LL:CC - 1: <&MyAllocator as std::alloc::Allocator>::deallocate - at RUSTLIB/core/src/alloc/mod.rs:LL:CC - 2: alloc::raw_vec::RawVecInner::<&MyAllocator>::deallocate - at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC - 3: as std::ops::Drop>::drop - at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC - 4: std::ptr::drop_glue::> - shim(Some(alloc::raw_vec::RawVec)) - at RUSTLIB/core/src/ptr/mod.rs:LL:CC - 5: std::ptr::drop_glue::> - shim(Some(std::vec::Vec)) - at RUSTLIB/core/src/ptr/mod.rs:LL:CC - 6: std::ptr::drop_glue::<(std::vec::Vec, std::vec::Vec)> - shim(Some((std::vec::Vec, std::vec::Vec))) - at RUSTLIB/core/src/ptr/mod.rs:LL:CC - 7: std::mem::drop::<(std::vec::Vec, std::vec::Vec)> - at RUSTLIB/core/src/mem/mod.rs:LL:CC - 8: main - at tests/fail/both_borrows/box-custom-alloc-aliasing.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail/both_borrows/box-custom-alloc-aliasing.tree.stderr b/src/tools/miri/tests/fail/both_borrows/box-custom-alloc-aliasing.tree.stderr deleted file mode 100644 index 44b7c2c13e72a..0000000000000 --- a/src/tools/miri/tests/fail/both_borrows/box-custom-alloc-aliasing.tree.stderr +++ /dev/null @@ -1,52 +0,0 @@ -error: Undefined Behavior: read access through at ALLOC[RANGE] is forbidden - --> tests/fail/both_borrows/box-custom-alloc-aliasing.rs:LL:CC - | -LL | let top = top_ptr.read(); - | ^^^^^^^^^^^^^^ Undefined Behavior occurred here - | - = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental - = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information - = help: the accessed tag is a child of the conflicting tag - = help: the conflicting tag has state Disabled which forbids this child read access -help: the accessed tag was created here - --> tests/fail/both_borrows/box-custom-alloc-aliasing.rs:LL:CC - | -LL | unsafe fn push(&self, ptr: NonNull) { - | ^^^^^ -help: the conflicting tag was created here, in the initial state Reserved - --> tests/fail/both_borrows/box-custom-alloc-aliasing.rs:LL:CC - | -LL | (Box::new_in([t], a) as Box<[T], A>).into_vec() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: the conflicting tag later transitioned to Disabled due to a foreign write access at offsets [RANGE] - --> tests/fail/both_borrows/box-custom-alloc-aliasing.rs:LL:CC - | -LL | self.top.set(top + 1); - | ^^^^^^^^^^^^^^^^^^^^^ - = help: this transition corresponds to a loss of read and write permissions - = note: stack backtrace: - 0: MyBin::push - at tests/fail/both_borrows/box-custom-alloc-aliasing.rs:LL:CC - 1: ::deallocate - at tests/fail/both_borrows/box-custom-alloc-aliasing.rs:LL:CC - 2: <&MyAllocator as std::alloc::Allocator>::deallocate - at RUSTLIB/core/src/alloc/mod.rs:LL:CC - 3: alloc::raw_vec::RawVecInner::<&MyAllocator>::deallocate - at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC - 4: as std::ops::Drop>::drop - at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC - 5: std::ptr::drop_glue::> - shim(Some(alloc::raw_vec::RawVec)) - at RUSTLIB/core/src/ptr/mod.rs:LL:CC - 6: std::ptr::drop_glue::> - shim(Some(std::vec::Vec)) - at RUSTLIB/core/src/ptr/mod.rs:LL:CC - 7: std::ptr::drop_glue::<(std::vec::Vec, std::vec::Vec)> - shim(Some((std::vec::Vec, std::vec::Vec))) - at RUSTLIB/core/src/ptr/mod.rs:LL:CC - 8: std::mem::drop::<(std::vec::Vec, std::vec::Vec)> - at RUSTLIB/core/src/mem/mod.rs:LL:CC - 9: main - at tests/fail/both_borrows/box-custom-alloc-aliasing.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/pass/box-custom-alloc-aliasing.rs b/src/tools/miri/tests/pass/box-custom-alloc-aliasing.rs index 6b3365839acd1..ab57ab246b4f3 100644 --- a/src/tools/miri/tests/pass/box-custom-alloc-aliasing.rs +++ b/src/tools/miri/tests/pass/box-custom-alloc-aliasing.rs @@ -1,10 +1,10 @@ //! Regression test for : //! If `Box` has a local allocator, then it can't be `noalias` as the allocator //! may want to access allocator state based on the data pointer. -//! Ensure that the `-Zmiri-tree-borrows-relax-custom-allocator-uniqueness` flag makes us -//! accept such code. -//@compile-flags: -Zmiri-tree-borrows -Zmiri-tree-borrows-relax-custom-allocator-uniqueness -Zmiri-tree-borrows-implicit-writes +//@revisions: stack tree tree_implicit_writes +//@[tree_implicit_writes]compile-flags: -Zmiri-tree-borrows -Zmiri-tree-borrows-implicit-writes +//@[tree]compile-flags: -Zmiri-tree-borrows #![feature(allocator_api)] use std::alloc::{AllocError, Allocator, Layout}; From 683f69991efe4d3abc5621e77eb9b26f185110a1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 24 Aug 2026 13:46:50 +0200 Subject: [PATCH 49/54] add new custom allocator test --- src/tools/miri/tests/pass/box-custom-alloc.rs | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/tools/miri/tests/pass/box-custom-alloc.rs b/src/tools/miri/tests/pass/box-custom-alloc.rs index 9a1a2f935921e..a8e31e10b942b 100644 --- a/src/tools/miri/tests/pass/box-custom-alloc.rs +++ b/src/tools/miri/tests/pass/box-custom-alloc.rs @@ -82,7 +82,44 @@ fn test2() { assert_eq!(42, with_dyn.hello()); } +fn test3() { + use std::ptr::{NonNull, slice_from_raw_parts_mut}; + use std::sync::atomic::{AtomicBool, Ordering}; + + static mut ALLOCATION: usize = 0; + static ALLOCATED: AtomicBool = AtomicBool::new(false); + + #[derive(Clone, Copy)] + struct A; + unsafe impl Allocator for A { + fn allocate(&self, layout: Layout) -> Result, AllocError> { + if layout != Layout::new::() { + return Err(AllocError); + } + if ALLOCATED.swap(true, Ordering::Acquire) { + return Err(AllocError); + } + NonNull::new(slice_from_raw_parts_mut(&raw mut ALLOCATION as *mut u8, 8)) + .ok_or(AllocError) + } + unsafe fn deallocate(&self, _ptr: NonNull, _layout: Layout) { + ALLOCATED.store(false, Ordering::Release); + } + } + + fn foo(a: A, b1: Box) { + assert_eq!(*b1, 1); + drop(b1); + let b3 = Box::new_in(3usize, a); + assert_eq!(*b3, 3); + } + + let b1 = Box::new_in(1usize, A); + foo(A, b1); +} + fn main() { test1(); test2(); + test3(); } From 6e9d6e4c321c2f81e13242cd564a076aaeb7a374 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 25 Aug 2026 07:59:31 +0200 Subject: [PATCH 50/54] Prepare for merging from rust-lang/rust This updates the rust-version file to 9bb55c8c865411b7d9dea6ff743e583d510d89f5. --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index e01a381d55fd9..1f775b7c771f8 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -c656540d6467dee1381f0cbd882412d6bd1cd5ae +9bb55c8c865411b7d9dea6ff743e583d510d89f5 From 2c9b143b0ff7721665bcf2f37909c20e833b0b7b Mon Sep 17 00:00:00 2001 From: Walnut <39544927+Walnut356@users.noreply.github.com> Date: Tue, 25 Aug 2026 02:55:25 -0500 Subject: [PATCH 51/54] fix tuple child ordering w/ PDB debug info --- src/etc/lldb_providers.py | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/etc/lldb_providers.py b/src/etc/lldb_providers.py index c5117c4c83f7c..f251fdb29ace2 100644 --- a/src/etc/lldb_providers.py +++ b/src/etc/lldb_providers.py @@ -1029,19 +1029,14 @@ def num_children(self) -> int: def get_child_index(self, name: str) -> int: if name.isdigit(): - return int(name) + return self.valobj.GetIndexOfChildWithName(f"__{name}") else: return -1 def get_child_at_index(self, index: int) -> Optional[SBValue]: - if self.is_variant: - field = self.type.GetFieldAtIndex(index + 1) - else: - field = self.type.GetFieldAtIndex(index) - element = self.valobj.GetChildMemberWithName(field.name) - return self.valobj.CreateValueFromData( - str(index), element.GetData(), element.GetType() - ) + return self.valobj.GetChildAtIndex( + self.valobj.GetIndexOfChildWithName(f"__{index}") + ).Clone(str(index)) def update(self): pass @@ -1060,12 +1055,15 @@ def num_children(self) -> int: return self.valobj.GetNumChildren() def get_child_index(self, name: str) -> int: - return self.valobj.GetIndexOfChildWithName(name) + if name.isdigit(): + return self.valobj.GetIndexOfChildWithName(f"__{name}") + else: + return -1 def get_child_at_index(self, index: int) -> Optional[SBValue]: - child: SBValue = self.valobj.GetChildAtIndex(index) - offset = self.valobj.GetType().GetFieldAtIndex(index).byte_offset - return self.valobj.CreateChildAtOffset(str(index), offset, child.GetType()) + return self.valobj.GetChildAtIndex( + self.valobj.GetIndexOfChildWithName(f"__{index}") + ).Clone(str(index)) def update(self): pass From 3be0b659541741e434ecf3efa10e77bec7db7af8 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 25 Aug 2026 10:42:03 +0200 Subject: [PATCH 52/54] update lockfile --- Cargo.lock | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4189a9d7d149f..90c8a59303c64 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1014,7 +1014,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73736a89c4aff73035ba2ed2e565061954da00d4970fc9ac25dcc85a2a20d790" dependencies = [ "dispatch2", - "nix", + "nix 0.30.1", "windows-sys 0.61.2", ] @@ -2265,9 +2265,9 @@ checksum = "803ec87c9cfb29b9d2633f20cba1f488db3fd53f2158b1024cbefb47ba05d413" [[package]] name = "libc" -version = "0.2.183" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "libffi" @@ -2539,10 +2539,11 @@ dependencies = [ "ipc-channel", "libc", "libffi", + "libffi-sys", "libloading", "measureme", "mio", - "nix", + "nix 0.31.3", "rand 0.10.1", "regex", "rustc_version", @@ -2595,6 +2596,18 @@ dependencies = [ "libc", ] +[[package]] +name = "nix" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" +dependencies = [ + "bitflags", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "nom" version = "7.1.3" From 926c5b8ab05217855f403c588ac6f684ac77dbd9 Mon Sep 17 00:00:00 2001 From: Maksim Bondarenkov Date: Tue, 25 Aug 2026 14:11:09 +0300 Subject: [PATCH 53/54] do not compress debuginfo for Cygwin when I updated Rust for MSYS, I got errors from gcc regarding -Wl,--compress-debug-sections=zlib flag being unsupported. so don't add it for all Cygwin hosts --- src/bootstrap/src/core/builder/cargo.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index c02fd567ac6c9..6f319d7da44d4 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -399,7 +399,9 @@ impl Cargo { // Do not enable Zlib compression on: // - Windows, because MSVC/PDB doesn't support it // - macOS, because its linker doesn't know the flag - if !self.target.is_windows() && !self.target.is_apple() { + // - Cygwin, because its linker may not support the flag + if !self.target.is_windows() && !self.target.is_apple() && !self.target.is_cygwin() + { // If we link through cc, we need the -Wl prefix. // If we don't, then we must not add it, because the linker wouldn't // understand it. From 8ff1a424d2de1ab2e15b665dbabe25994c1daaa7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 25 Aug 2026 14:19:00 +0200 Subject: [PATCH 54/54] make trivial ABI check resilient against new repr --- compiler/rustc_abi/src/lib.rs | 8 ++++++++ compiler/rustc_const_eval/src/interpret/call.rs | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index ba5119ee228ad..7cfb93ca1b86d 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -184,6 +184,14 @@ impl ReprOptions { self.flags.contains(ReprFlags::IS_C) } + /// Returns whether this is (implicitly or explicitly) `repr(Rust)`, i.e., its layout + /// is defined by Rust and we make no stable commitments. + #[inline] + pub fn rust(&self) -> bool { + // `linear` is currently just an internal flag we set on Box; that's still `repr(Rust)`. + !self.c() & !self.simd() & !self.scalable() & !self.transparent() + } + #[inline] pub fn packed(&self) -> bool { self.pack.is_some() diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index c378a70da4b2b..d10b844bf3500 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -97,7 +97,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } else if adt_def.repr().c() { interp_ok(false) } else { - // Must be repr(Rust). + // Can't be SIMD or Scalable (since this is a 1-ZST); only Rust is left. + assert!(adt_def.repr().rust()); interp_ok(true) } }